/proc/$pid/status の RssFile の挙動を確かめる
/proc/$pid/status
に含まれる RssFile
という数値がどのように上下するのか分からなかったので、検証コードで挙動を確かめた
結論を先に書いておくと、プロセスが mmap(2) + MAP_FILE (ファイルの mmap ) しているサイズということらしくて、難しいもんでもなかった
Linux カーネルのドキュメントによる説明
https://www.kernel.org/doc/Documentation/filesystems/proc.txt には下記の通りの説明しかない
RssFile size of resident file mappings
検証環境
Vagrant + CentOS7.3 3.10.0-514.26.2.el7.x86_64
検証内容
- 検証用コードを実行して、
/proc/meminfo
/proc/$pid/status
ps
やtop
がどのような数値を返すかを観察する - 検証用コードを実行中に、
sysctl vm.drop_caches=3
を実行して、上記の数値がどのように変化するかを観察する
検証用コード
1GB のテキストファイルを mmap(2) した後に、ポインタ操作でメジャーフォルトを起こしてデータをページキャッシュに載せるコードになる
CFLAGS="-g -O0 -std=gnu99 -W -Wall" o=`basename $0` o=".${o%.*}" gcc ${CFLAGS} -o $o $0 && ./$o $*; exit #endif #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <fcntl.h> #include <sys/mman.h> int main() { int fd = open("/tmp/1000mb.txt", O_RDWR); if (fd == -1) { perror("open"); exit(1); } size_t size = 1024 * 1024 * 1024; char *p = (char *)mmap(NULL, size, PROT_READ, MAP_FILE|MAP_SHARED, fd, 0); if (p == MAP_FAILED) { perror("failed mmap"); exit(2); } char c; for (size_t i = 0; i < size; i += 4096) { /* cause major fault */ c = p[i]; /* to remove -Wunused-but-set-variable */ c = c; } /* Inactive(file) -> Active(file) */ for (size_t i = 0; i < size; i += 4096) { c = p[i]; c = c; } pause(); exit(0); }
検証手順
mmap(2) 用のファイルを作る
ファイルサイズはホストの搭載 RAM サイズに合わせて調整してください
perl -e 'print 1 x 1024 x 1024 x 1024' > /tmp/1000mb.txt sync
ページキャッシュ, inode キャシュ, dentry キャッシュを破棄する
sudo sysctl vm.drop_caches=3
キャッシュを吹き飛ばしておいて数値の変化を把握しやくするのが目的
/proc/meminfo
の値を記録する
[vagrant@localhost ~]$ cat /proc/meminfo MemTotal: 3881976 kB MemFree: 3705744 kB MemAvailable: 3608720 kB Buffers: 0 kB Cached: 38408 kB SwapCached: 0 kB Active: 74440 kB Inactive: 25112 kB Active(anon): 61172 kB Inactive(anon): 9136 kB Active(file): 13268 kB Inactive(file): 15976 kB Unevictable: 0 kB Mlocked: 0 kB SwapTotal: 1572860 kB SwapFree: 1572860 kB Dirty: 0 kB Writeback: 0 kB AnonPages: 61164 kB Mapped: 25140 kB Shmem: 9140 kB Slab: 35552 kB SReclaimable: 13184 kB SUnreclaim: 22368 kB KernelStack: 1888 kB PageTables: 4672 kB NFS_Unstable: 0 kB Bounce: 0 kB WritebackTmp: 0 kB CommitLimit: 3513848 kB Committed_AS: 328436 kB VmallocTotal: 34359738367 kB VmallocUsed: 11976 kB VmallocChunk: 34359724032 kB HardwareCorrupted: 0 kB AnonHugePages: 10240 kB HugePages_Total: 0 HugePages_Free: 0 HugePages_Rsvd: 0 HugePages_Surp: 0 Hugepagesize: 2048 kB DirectMap4k: 49088 kB DirectMap2M: 4145152 kB
検証用コードを実行する
bash mmap.c
検証用コードを実行しているプロセスの /proc/$pid/status
を記録する
RssFile: 1047928 kB
となり、 mmap(2) したファイルサイズ (+α … libc 等のライブラリ ) 分がカウントされている- VmPeak , VmSize, VmHWM, VmRSS にもカウントされている
[vagrant@localhost ~]$ cat /proc/$(pgrep .mmap)/status Name: .mmap State: S (sleeping) Tgid: 2544 Ngid: 0 Pid: 2544 PPid: 2537 TracerPid: 0 Uid: 1000 1000 1000 1000 Gid: 1000 1000 1000 1000 FDSize: 256 Groups: 1000 VmPeak: 1052728 kB ⭐ VmSize: 1052728 kB ⭐ VmLck: 0 kB VmPin: 0 kB VmHWM: 1048732 kB ⭐ VmRSS: 1048732 kB ⭐ RssAnon: 84 kB RssFile: 1048648 kB 🔥 RssShmem: 0 kB VmData: 48 kB VmStk: 132 kB VmExe: 4 kB VmLib: 1880 kB VmPTE: 2076 kB VmSwap: 0 kB Threads: 1 SigQ: 0/15081 SigPnd: 0000000000000000 ShdPnd: 0000000000000000 SigBlk: 0000000000000000 SigIgn: 0000000000000000 SigCgt: 0000000000000000 CapInh: 0000000000000000 CapPrm: 0000000000000000 CapEff: 0000000000000000 CapBnd: 0000001fffffffff CapAmb: 0000000000000000 Seccomp: 0 Cpus_allowed: 3 Cpus_allowed_list: 0-1 Mems_allowed: 00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000001 Mems_allowed_list: 0 voluntary_ctxt_switches: 6324 nonvoluntary_ctxt_switches: 1
検証用コードを実行しているときの /proc/meminfo を記録する
- 🔥 を付けた項目にカウントされている
[vagrant@localhost ~]$ cat /proc/meminfo MemTotal: 3881976 kB MemFree: 2631564 kB MemAvailable: 3535780 kB Buffers: 0 kB Cached: 1108548 kB 🔥 SwapCached: 0 kB Active: 75236 kB Inactive: 1094604 kB 🔥 Active(anon): 61296 kB Inactive(anon): 9136 kB Active(file): 13940 kB Inactive(file): 1085468 kB 🔥 Unevictable: 0 kB Mlocked: 0 kB SwapTotal: 1572860 kB SwapFree: 1572860 kB Dirty: 12 kB Writeback: 0 kB AnonPages: 61440 kB Mapped: 1073720 kB 🔥 Shmem: 9140 kB Slab: 37416 kB SReclaimable: 15032 kB SUnreclaim: 22384 kB KernelStack: 1920 kB PageTables: 6800 kB NFS_Unstable: 0 kB Bounce: 0 kB WritebackTmp: 0 kB CommitLimit: 3513848 kB Committed_AS: 329076 kB VmallocTotal: 34359738367 kB VmallocUsed: 11976 kB VmallocChunk: 34359724032 kB HardwareCorrupted: 0 kB AnonHugePages: 10240 kB HugePages_Total: 0 HugePages_Free: 0 HugePages_Rsvd: 0 HugePages_Surp: 0 Hugepagesize: 2048 kB DirectMap4k: 49088 kB DirectMap2M: 4145152 kB
top の数値を記録する
- RES と SHR どちらにもカウントされている
top - 08:41:25 up 22 min, 2 users, load average: 0.06, 0.04, 0.05 Tasks: 1 total, 0 running, 1 sleeping, 0 stopped, 0 zombie %Cpu(s): 0.2 us, 0.4 sy, 0.0 ni, 99.1 id, 0.3 wa, 0.0 hi, 0.1 si, 0.0 st KiB Mem : 3881976 total, 2629904 free, 105144 used, 1146928 buff/cache KiB Swap: 1572860 total, 1572860 free, 0 used. 3535032 avail Mem PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 2544 vagrant 20 0 1052728 1.000g🔥1.000g🔥S 0.0 27.0 0:01.02 .mmap
ps auxf の数値を記録する
RSS にもカウントされている
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND vagrant 2544 1.7 27.0 1052728 1048732 pts/0 S+ 08:40 0:01 | \_ ./.mmap
もう一度 ページキャッシュ, inode キャシュ, dentry キャッシュを破棄する
sudo sysctl vm.drop_caches=3
vm.drop_caches によるページキャッシュの破棄は mmap(2) しているページには作用しないようだ ( 正確なところはコードを読んで確かめたい)
[vagrant@localhost ~]$ cat /proc/meminfo MemTotal: 3881976 kB MemFree: 2652528 kB MemAvailable: 3535704 kB Buffers: 0 kB Cached: 1087540 kB SwapCached: 0 kB Active: 74716 kB Inactive: 1074168 kB Active(anon): 61348 kB Inactive(anon): 9136 kB Active(file): 13368 kB Inactive(file): 1065032 kB Unevictable: 0 kB Mlocked: 0 kB SwapTotal: 1572860 kB SwapFree: 1572860 kB Dirty: 20 kB Writeback: 0 kB AnonPages: 61368 kB Mapped: 1073720 kB Shmem: 9140 kB Slab: 37396 kB SReclaimable: 14968 kB SUnreclaim: 22428 kB KernelStack: 1920 kB PageTables: 6800 kB NFS_Unstable: 0 kB Bounce: 0 kB WritebackTmp: 0 kB CommitLimit: 3513848 kB Committed_AS: 329076 kB VmallocTotal: 34359738367 kB VmallocUsed: 11976 kB VmallocChunk: 34359724032 kB HardwareCorrupted: 0 kB AnonHugePages: 10240 kB HugePages_Total: 0 HugePages_Free: 0 HugePages_Rsvd: 0 HugePages_Surp: 0 Hugepagesize: 2048 kB DirectMap4k: 49088 kB DirectMap2M: 4145152 kB [vagrant@localhost ~]$
検証用コードを実行しているプロセスを止めた後の /proc/meminfo
を記録する
- Mapped が減少した
- Cached, Inactve(file) は減らない ( ページキャッシュとして残り続けている )
尚、Active(file)
か Inactive(file)
かは今回の検証結果を左右するものでない ( http://mkosaki.blog46.fc2.com/blog-entry-884.html を読まれたし )
[vagrant@localhost ~]$ cat /proc/meminfo MemTotal: 3881976 kB MemFree: 2654592 kB MemAvailable: 3537768 kB Buffers: 0 kB Cached: 1087540 kB SwapCached: 0 kB Active: 74412 kB Inactive: 1074140 kB Active(anon): 61016 kB Inactive(anon): 9136 kB Active(file): 13396 kB Inactive(file): 1065004 kB Unevictable: 0 kB Mlocked: 0 kB SwapTotal: 1572860 kB SwapFree: 1572860 kB Dirty: 20 kB Writeback: 0 kB AnonPages: 61084 kB Mapped: 25140 kB 🔥 Shmem: 9140 kB Slab: 37348 kB SReclaimable: 14968 kB SUnreclaim: 22380 kB KernelStack: 1888 kB PageTables: 4672 kB NFS_Unstable: 0 kB Bounce: 0 kB WritebackTmp: 0 kB CommitLimit: 3513848 kB Committed_AS: 328436 kB VmallocTotal: 34359738367 kB VmallocUsed: 11976 kB VmallocChunk: 34359724032 kB HardwareCorrupted: 0 kB AnonHugePages: 10240 kB HugePages_Total: 0 HugePages_Free: 0 HugePages_Rsvd: 0 HugePages_Surp: 0 Hugepagesize: 2048 kB DirectMap4k: 49088 kB DirectMap2M: 4145152 kB