読者です 読者をやめる 読者になる 読者になる

ページキャッシュの実験

linux

寝る前にどうしても試してみたかったのでもう一つ。


Linuxでは読み書きしたファイルがページ単位で余裕のあるメモリにキャッシュされる、という話は知っていたのですが、仕組みについてはあまり理解していませんでした。

で、例の本でとてもわかりやすく実験方法も書いてあったので実験してみます。

まず、そのまえにページ・キャッシュの仕組みをメモ。

  • ページ・キャッシュにはページの活性*1を表すActive/Inactiveという状態と、ディスクとの同期状態を表すDirty/Writebackという状態がある。
  • ページの活性は、Active(2) > Active(1) > Inactive(2) > Inactive(1)、の順で高い。初回の書き込みでInactive。その後、Readされる毎にActive方向に遷移していく。
  • ページがwriteされると、Inactive(2)に遷移。ページが回収されていくとInactive(1)または空きメモリ(/proc/meminfoでいうところのMemFree)に。
  • ページ・キャッシュがディスクへsyncされていない分がDirty。sync中はWriteback。
  • ちなみにディスクへのsyncはpdflushが常駐して担当。
  • Active/InactiveとDirtyは独立して遷移する。
  • (個人的な推測→)多分、空きメモリ(MemFree)とInactiveの値の合計が「実際に使用可能なメモリ量」ではなかろうか。目安として。

実験の手順は、

  • 100MByteのファイルをwrite
  • そのファイルをread, read, read!
  • その都度, /proc/meminfoの値を記録

するだけ。

やってみた。

komamitsu@potato:~/lab/misc/meminfo$ sudo cat /proc/meminfo > before
komamitsu@potato:~/lab/misc/meminfo$ dd if=/dev/zero of=hoge bs=1M count=100
100+0 records in
100+0 records out
104857600 bytes (105 MB) copied, 0.798606 s, 131 MB/s
komamitsu@potato:~/lab/misc/meminfo$ sudo cat /proc/meminfo > step1
komamitsu@potato:~/lab/misc/meminfo$ cat hoge > /dev/null
komamitsu@potato:~/lab/misc/meminfo$ sudo cat /proc/meminfo > step2
komamitsu@potato:~/lab/misc/meminfo$ cat hoge > /dev/null
komamitsu@potato:~/lab/misc/meminfo$ sudo cat /proc/meminfo > step3


結果はこんな感じ。

before step1 step2 step3
MemTotal 968376 kB 968376 kB 968376 kB 968376 kB
MemFree 429460 kB 325140 kB 325176 kB 325176 kB
Cached 98852 kB 201292 kB 201300 kB 201304 kB
Active 348636 kB 348776 kB 348776 kB 451176 kB
Inactive 130900 kB 233332 kB 233356 kB 130960 kB
Dirty 4 kB 15768 kB 32 kB 36 kB
Writeback 0 kB 0 kB 0 kB 0 kB

初っ端のwriteでMemFreeが減ってその分、Inactiveが増えている(同時にCachedも)。その後のreadでは変化せず(内部的にはInactive(1)->(2)?)、二回目のreadでInactiveからActiveに遷移している。
ちなみにDirtyの方は、初回のwrite後、15MBtye程度の未syncのページが存在しているが、readのタイミングではほとんどsync済み、のようにみえる。


今回の実験では事象をシンプルにしているので結構わかりやすいが、実際のアプリケーションでは複雑になってくるはずなので、上記のようにわかりやすく遷移しないような気はするのだけど、まぁイメージとして抑えておくといいかなぁ、と。

*1:件の本では使用頻度とあるが、writeでInactiveになることを踏まえると活性の方がわかりやすい気がする