Linux下谁在消耗我们的cache
原创文章,转载请注明: 转载自系统技术非业余研究
本文链接地址: Linux下谁在消耗我们的cache
Linux下对文件的访问和设备的访问通常会被cache起来加快访问速度,这个是系统的默认行为。 而cache需要耗费我们的内存,虽然这个内存最后可以通过echo 3>/proc/sys/vm/drop_caches这样的命令来主动释放。但是有时候我们还是需要理解谁消耗了我们的内存。
我们来先了解下内存的使用情况:
[root@my031045 ~]# free total used free shared buffers cached Mem: 24676836 626568 24050268 0 30884 508312 -/+ buffers/cache: 87372 24589464 Swap: 8385760
有了伟大的systemtap, 我们可以用stap脚本来了解谁在消耗我们的cache了:
#这个命令行用来调查谁在加数据入page_cache [root@my031045 ~]# stap -e 'probe vfs.add_to_page_cache {printf("dev=%d, devname=%s, ino=%d, index=%d, nrpages=%d\n", dev, devname, ino, index, nrpages )}' ... dev=2, devname=N/A, ino=0, index=2975, nrpages=1777 dev=2, devname=N/A, ino=0, index=3399, nrpages=2594 dev=2, devname=N/A, ino=0, index=3034, nrpages=1778 dev=2, devname=N/A, ino=0, index=3618, nrpages=2595 dev=2, devname=N/A, ino=0, index=1694, nrpages=106 dev=2, devname=N/A, ino=0, index=1703, nrpages=107 dev=2, devname=N/A, ino=0, index=1810, nrpages=210 dev=2, devname=N/A, ino=0, index=1812, nrpages=211 ...
这时候我们拷贝个大文件:
[chuba@my031045 ~]$ cp huge_foo.file bar #这时候我们可以看到文件的内容被猛的添加到cache去: ... dev=8388614, devname=sda6, ino=2399271, index=39393, nrpages=39393 dev=8388614, devname=sda6, ino=2399271, index=39394, nrpages=39394 dev=8388614, devname=sda6, ino=2399271, index=39395, nrpages=39395 dev=8388614, devname=sda6, ino=2399271, index=39396, nrpages=39396 dev=8388614, devname=sda6, ino=2399271, index=39397, nrpages=39397 dev=8388614, devname=sda6, ino=2399271, index=39398, nrpages=39398 dev=8388614, devname=sda6, ino=2399271, index=39399, nrpages=39399 dev=8388614, devname=sda6, ino=2399271, index=39400, nrpages=39400 dev=8388614, devname=sda6, ino=2399271, index=39401, nrpages=39401 dev=8388614, devname=sda6, ino=2399271, index=39402, nrpages=39402 dev=8388614, devname=sda6, ino=2399271, index=39403, nrpages=39403 dev=8388614, devname=sda6, ino=2399271, index=39404, nrpages=39404 dev=8388614, devname=sda6, ino=2399271, index=39405, nrpages=39405 dev=8388614, devname=sda6, ino=2399271, index=39406, nrpages=39406 dev=8388614, devname=sda6, ino=2399271, index=39407, nrpages=39407 dev=8388614, devname=sda6, ino=2399271, index=39408, nrpages=39408 dev=8388614, devname=sda6, ino=2399271, index=39409, nrpages=39409 dev=8388614, devname=sda6, ino=2399271, index=39410, nrpages=39410 dev=8388614, devname=sda6, ino=2399271, index=39411, nrpages=39411 ...
此外加入我们想了解下系统的cache都谁在用呢, 那个文件用到多少页了呢?
我们有个脚本可以做到,这里非常谢谢 子团 让我使用他的代码。
[chuba@my031045 ~]# stap -g viewcache.stp 在另外的shell里面 [chuba@my031045 ~]# dmesg ... inode: 116397109, num: 5 inode: 116397111, num: 2 inode: 116397112, num: 1 inode: 116397149, num: 2 inode: 116397152, num: 1 inode: 116397336, num: 2 inode: 116397343, num: 1 inode: 116397371, num: 4 inode: 116397372, num: 2 ...
非常清楚的看出来每个inode占用了多少页,用工具转换下就知道哪个文件耗费了多少内存。
另外小TIPS:
从inode到文件名的转换
find / -inum your_inode
从文件名到inode的转换
stat -c “%i” your_filename
或者 ls -i your_filename
我们套用了下就马上知道那个文件占用的cache很多。
[chuba@my031045 ~]$ sudo find / -inum 2399248 /home/chuba/kernel-debuginfo-2.6.18-164.el5.x86_64.rpm
玩的开心。
参考资料:
page cache和buffer cache的区别:
这篇文章总结的最靠谱: http://blog.chinaunix.net/u/1595/showart.php?id=2209511
后记:
linux下有个这样的系统调用可以知道页面的状态:mincore – determine whether pages are resident in memory
同时有人作个脚本fincore更方便大家的使用, 点击下载fincore
后来子团告诉我还有这个工具: https://code.google.com/p/linux-ftools/
Post Footer automatically generated by wp-posturl plugin for wordpress.
图片上的谷歌拼音挺显眼。
Yu Feng Reply:
September 25th, 2010 at 9:26 pm
确实是 截屏的时候没注意。
好文!
Yu Feng Reply:
September 26th, 2010 at 11:39 am
谢谢朱哥哥的鼓励。
哈哈 这个好!前天还在想怎么看内存用到哪去了。。
用ps -eo pid,rss –sort rss看到的数据还是小于实际占用量的
灰常感谢!
学习了,很好的文章!
期待褚霸哥改天给大家讲讲现在kernel体系里buffer和cache的概念
Yu Feng Reply:
September 26th, 2010 at 4:31 pm
子团兄见笑了,在你面前,俺那敢呀。
喔 是这样子,拜读啦,,…
无论从字里行间都能看得出楼主是很用心的!
关掉你的手机,慢慢地闭上眼睛,想想我,想想月饼,你会发现我和月饼一样可爱!中秋节快乐!
补充一下,free的”cache”里也包括了“已使用的”共享内存数据。
“已使用的”共享内存数据 是指shmget申请下来后真正写过的数据。
共享内存其实是通过mmap file来实现的,而所有的mmap的内存都是属于file back的,这些内存理所当然的就被统计进cache里了
找老找去找到自家兄弟田里了,写的很清晰,多谢霸爷
Yu Feng Reply:
May 30th, 2011 at 10:45 am
客气了呀,哥哥!
好文,通俗易懂,转走了!
你好,霸爷。我这边想跟踪slab分配是被哪个进程的什么系统调用导致的。
通过编写stap脚本,目前知道的只能获取进程,但是无法获取到进程是调用了哪个系统调用。请问如何获得?
Yu Feng Reply:
March 20th, 2015 at 11:56 am
在系统调用上搞个probe点就好了呀。
[root@131-PBS-DG-SZ ~]# stap -e ‘probe vfs.add_to_page_cache {printf(“dev=%d, devname=%s, ino=%d, index=%d, nrpages=%d\n”, dev, devname, ino, index, nrpages )}’
semantic error: while resolving probe point: identifier ‘kernel’ at /usr/share/systemtap/tapset/linux/vfs.stp:719:2
source: kernel.function(“add_to_page_cache”)
^
semantic error: missing x86_64 kernel/module debuginfo [man warning::debuginfo] under ‘/lib/modules/3.8.13-16.2.1.el6uek.x86_64/build’
semantic error: while resolving probe point: identifier ‘vfs’ at :1:7
source: probe vfs.add_to_page_cache {printf(“dev=%d, devname=%s, ino=%d, index=%d, nrpages=%d\n”, dev, devname, ino, index, nrpages )}
^
semantic error: no match
Pass 2: analysis failed. [man error::pass2]
oracle linux 6.5
viewcache.stp 这个脚本不过呀!!!
[][root@esdev1 /]# stap -g viewcache.stp
/tmp/stappcx18d/stap_ddc443ddff29f6fb940e7eb81a00174d_12741_src.c: In function ‘add_page_to_active_list’:
/tmp/stappcx18d/stap_ddc443ddff29f6fb940e7eb81a00174d_12741_src.c:51: error: ‘struct zone’ has no member named ‘active_list’
/tmp/stappcx18d/stap_ddc443ddff29f6fb940e7eb81a00174d_12741_src.c:52: error: ‘struct zone’ has no member named ‘nr_active’
/tmp/stappcx18d/stap_ddc443ddff29f6fb940e7eb81a00174d_12741_src.c: In function ‘add_page_to_inactive_list’:
/tmp/stappcx18d/stap_ddc443ddff29f6fb940e7eb81a00174d_12741_src.c:58: error: ‘struct zone’ has no member named ‘inactive_list’
/tmp/stappcx18d/stap_ddc443ddff29f6fb940e7eb81a00174d_12741_src.c:59: error: ‘struct zone’ has no member named ‘nr_inactive’
/tmp/stappcx18d/stap_ddc443ddff29f6fb940e7eb81a00174d_12741_src.c: In function ‘function_viewcache’:
/tmp/stappcx18d/stap_ddc443ddff29f6fb940e7eb81a00174d_12741_src.c:427: error: ‘struct zone’ has no member named ‘nr_active’
/tmp/stappcx18d/stap_ddc443ddff29f6fb940e7eb81a00174d_12741_src.c:428: error: ‘struct zone’ has no member named ‘nr_inactive’
/tmp/stappcx18d/stap_ddc443ddff29f6fb940e7eb81a00174d_12741_src.c:439: error: ‘struct zone’ has no member named ‘active_list’
/tmp/stappcx18d/stap_ddc443ddff29f6fb940e7eb81a00174d_12741_src.c:442: error: ‘struct zone’ has no member named ‘nr_active’
/tmp/stappcx18d/stap_ddc443ddff29f6fb940e7eb81a00174d_12741_src.c:468: error: ‘struct zone’ has no member named ‘inactive_list’
/tmp/stappcx18d/stap_ddc443ddff29f6fb940e7eb81a00174d_12741_src.c:471: error: ‘struct zone’ has no member named ‘nr_inactive’
make[1]: *** [/tmp/stappcx18d/stap_ddc443ddff29f6fb940e7eb81a00174d_12741_src.o] Error 1
make: *** [_module_/tmp/stappcx18d] Error 2
WARNING: kbuild exited with status: 2
Pass 4: compilation failed. [man error::pass4]