ことぶきぶろぐ

日々の記録

試して理解 Linuxのしくみを読んだ時のメモ

「試して理解Linuxのしくみ」を読んだ時のメモです。 実際にコードを実行しながら学ぶことで、プロセス、メモリ、ストレージ周りのしくみの理解が深まりました。しくみがわかることでシステムのトラブルシューティングなどに役立つのかなと思います。

2章 ユーザーモードで実現する機能

3章 プロセス管理

  • Linuxにおいて、プロセス生成には2つの目的がある

    • 同じプログラムの処理を複数のプロセスに分けて処理する(例 webサーバーによる複数リクエストの受付)。fork関数のみ使われる。
    • 全く別のプログラムを生成する。(bashから新規プログラムの生成)

    ​ fork関数とexecve関数が使われる。

  • fork関数は、親プロセスをもとに子プロセスを生成する。親プロセスのメモリから子プロセスのメモリを複製し、親プロセスと子プロセスが違うコードを実行するように分岐する。

  • execve関数は、全く別のプログラムを生成するのに使われる。execve関数を発行したプロセスのメモリの内容を、実行ファイルのデータで上書きして新規のプロセスを生成する。このようにexecve関数では、プロセスの数は変わらず、あるプロセスを別のプロセスに置き換える。

  • _exit関数は、プログラム終了時に利用される。プロセスに割り当てていたメモリをすべて回収する。

4章 プロセススケジューラー

  • プロセススケジューラーとは、複数のプロセスを同時に動作させるためのLinuxカーネルの機能(実際には順番に一定時間CPU時間を割り当てられて実行する)
  • 一つのCPU上で同時に処理するプロセスは一つだけ
  • 複数プロセスが実行可能な場合、個々のプロセスを適当な長さの時間(タイムスライス)ごとにCPU上で順番に処理する
  • プロセスの状態

    • 実行状態(現在論理CPUを使っている)
    • 実行待ち状態(CPU時間の割当を待っている)
    • スリープ状態(何らかのイベントが発生するのを待っている。イベント発生までCPU時間は使わない。)
    • ゾンビ状態
  • CPUのアイドル状態とは、アイドルプロセスという特殊なプロセスが割り当てられてCPUの動作が休止している状態。実行待ち、実行状態のプロセスが存在しない時にアイドル状態になる。sarコマンドのidleの部分。

  • コンテキストスイッチとは、論理CPU上で動作するプロセスが切り替わること。頻繁に発生するとオーバーヘッドにより性能が低下する。
  • スループットは、単位時間あたりの総仕事量。高いほどよい
  • レイテンシは、それぞれの処理開始から終了までの経過時間。短いほどよい。
  • 複数の論理CPUが存在する場合には、ロードバランサー、グローバルスケジューラー機能によって、プロセスを公平に分配する。
  • timeコマンドで、プロセスの開始から終了までの経過時間と、プロセスが実際に論理CPUを使用した時間を確認できる。
  • nice()システムコールでプロセスの実行優先度を変更できる。0がデフォルト。-19~20で数値が低いほど優先度が高い。rootユーザーだけ優先度を高くできる。システムに存在するプロセスは平等にCPU時間を得るが、nice値を変更することで特定のプロセスのCPU時間を増減させることができる。

わからないこと

  • ゾンビ状態

ゾンビプロセスをなかなか見ることができない理由 | NHN Cloud Meetup

5章 メモリ管理

  • Linuxカーネルのメモリ管理システムでシステムに搭載されている全メモリを管理している。
  • Out Of Memoryとは、開放可能なメモリ領域もない状態でメモリ使用量がいっぱいになること。この時、メモリ管理システムはOOM killerという機能により適当なプロセスを選んで強制終了する。この挙動はOOM発生時にシステムを強制終了に変更することができる。
  • Linuxではプロセスにメモリを割り当てる際に、物理メモリのアドレスを直接割り当てるのではなく、仮想メモリアドレスを割り当てる。プロセスは仮想メモリアドレスを介して間接的に物理メモリにアクセスする。
  • 仮想メモリアドレスと物理メモリアドレスのマッピングの情報は、カーネルのメモリのページテーブルに保持される。ページテーブルの一つの対のデーターをページテーブルエントリーと呼ぶ。
  • 仮想メモリアドレスを利用するメリット
    • メモリの断片化を防ぐ
    • 別用途のメモリへのアクセスを防ぐ
    • マルチプロセスの扱いを簡単に
  • ファイルマップは、ファイルの領域を仮想アドレス空間上にメモリマップする機能。ファイルの内容を物理メモリに読み出して仮想メモリアドレスにマッピングする。マップされた領域から読み出しや書き込みができる。その後、所定のタイミングでストレージデバイスのファイルに書き戻される。普通は、ファイルを開いてread()やwrite()のシステムコールでストレージ上のファイルを操作する。
  • デマンドページングは、プロセスに仮想アドレスを割り当てるが、物理メモリの割当ては、仮想アドレス空間のページに最初にアクセスした時に実施する機能。これにより、無駄なメモリ消費を避ける。
  • コピーオンライトは、プロセス生成のfork()システムコールを高速化する。親プロセスから子プロセスを生成時には、ページテーブルだけをコピーして親プロセスと子プロセスが共有のメモリを利用する。プロセスに書き込みを行う時に、実際にプロセスのメモリのコピーを作成する。

6章 記憶階層

記憶装置 (アクセス速度は上から順に速い)
レジスタ(CPU内)
キャッシュメモリ(CPU内or外)
メモリ
ストレージデバイス
  • キャッシュメモリは、CPUのレジスタ上での計算速度とメモリへのアクセス速度の差による遅延をなくすためのもの。メモリへのアクセス速度は、レジスタ上の計算に比べてとても遅い。そのため、計算が早くてもメモリへの読み書きの速度がボトルネックになり処理全体が遅延してしまう。キャッシュメモリからレジスタへのアクセスは、メモリからレジスタへのアクセスの数十倍高速である。メモリからレジスタへデータを読み出す際に、まずはキャッシュメモリがデータを読み込み、保存する。レジスタキャッシュメモリからデータを読み込む。再度同じデータをCPUが読み出したい場合、キャッシュメモリから高速に読み出すことができる。

     書き込みの場合は、CPUはレジスタで書き換えたデータをキャッシュメモリに書き込む。変更された(ダーディーである)という印をキャッシュライン(キャッシュメモリ上のデータ)につける。ダーティーなキャッシュラインはすぐにメモリに書き込まれず、所定のタイミングで書き込まれる。これをライトバックと呼ぶ。

  • ページキャッシュは、ストレージ上のファイルデータをメモリにキャッシュすること。プロセスがファイルデータを読み出す時、まずはカーネルのメモリ領域にファイルデータをページキャッシュとしてコピーする。そして、ページキャッシュをプロセスのメモリ領域にコピーする。再度、同じデータを読み出すときには、ページキャッシュからデータを高速に読み出すことができる。  書き込みの場合は、プロセスのメモリ上のデータを書き換えた後、ページキャッシュのデータだけを書き換えて、ダーティーマークをつけておく。ダーディなページは所定のタイミングでストレージに書き込まれる。これをライトバックと呼ぶ。

  • ページキャッシュはメモリに空き容量がある場合、作成され続ける。メモリの空き容量がいっぱいになってくると、ページキャッシュが解放される。解放の時は、ダーディーではないキャッシュを優先して解放する。足りない場合は、ダーディーなページをストレージに書き込んでから解放する。この時ストレージアクセスが生じるため、システム性能が劣化する。

  • sar -d -p コマンドで、ストレージデバイスごとにI/Oの統計情報を確認できる。

  • sar -B コマンドでページインとページアウトの量の統計情報を確認できる。
    • ページアウトは、ストレージからページキャッシュにデータを読み込むこと
    • ページインは、ページキャッシュからストレージにデータを書き出すこと

7章 ファイルシステム