ページキャッシュの実験
寝る前にどうしても試してみたかったのでもう一つ。
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になることを踏まえると活性の方がわかりやすい気がする