Home > 工具介绍 > Linux下谁在消耗我们的cache

Linux下谁在消耗我们的cache

September 25th, 2010

原创文章,转载请注明: 转载自系统技术非业余研究

本文链接地址: 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占用了多少页,用工具转换下就知道哪个文件耗费了多少内存。

点击下载viewcache.stp

另外小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.

  1. zhang
    September 25th, 2010 at 21:24 | #1

    图片上的谷歌拼音挺显眼。

    Yu Feng Reply:

    确实是 截屏的时候没注意。

  2. September 26th, 2010 at 11:02 | #2

    好文!

    Yu Feng Reply:

    谢谢朱哥哥的鼓励。

  3. September 26th, 2010 at 12:11 | #3

    哈哈 这个好!前天还在想怎么看内存用到哪去了。。
    用ps -eo pid,rss –sort rss看到的数据还是小于实际占用量的
    灰常感谢!

  4. September 26th, 2010 at 12:49 | #4

    学习了,很好的文章!

  5. zituan
    September 26th, 2010 at 16:30 | #5

    期待褚霸哥改天给大家讲讲现在kernel体系里buffer和cache的概念

    Yu Feng Reply:

    子团兄见笑了,在你面前,俺那敢呀。

  6. September 29th, 2010 at 01:37 | #6

    喔 是这样子,拜读啦,,…

  7. October 2nd, 2010 at 11:31 | #7

    无论从字里行间都能看得出楼主是很用心的!

  8. October 7th, 2010 at 21:54 | #8

    关掉你的手机,慢慢地闭上眼睛,想想我,想想月饼,你会发现我和月饼一样可爱!中秋节快乐!

  9. cycker@qq.com
    October 8th, 2010 at 18:33 | #9

    补充一下,free的”cache”里也包括了“已使用的”共享内存数据。
    “已使用的”共享内存数据 是指shmget申请下来后真正写过的数据。

  10. zituan
    October 8th, 2010 at 23:01 | #10

    共享内存其实是通过mmap file来实现的,而所有的mmap的内存都是属于file back的,这些内存理所当然的就被统计进cache里了

  11. kongjian
    May 26th, 2011 at 18:40 | #11

    找老找去找到自家兄弟田里了,写的很清晰,多谢霸爷

    Yu Feng Reply:

    客气了呀,哥哥!

  12. November 13th, 2013 at 15:52 | #12

    好文,通俗易懂,转走了!

  13. chinaxing
    March 20th, 2015 at 10:59 | #13

    你好,霸爷。我这边想跟踪slab分配是被哪个进程的什么系统调用导致的。

    通过编写stap脚本,目前知道的只能获取进程,但是无法获取到进程是调用了哪个系统调用。请问如何获得?

    Yu Feng Reply:

    在系统调用上搞个probe点就好了呀。

  14. shark
    July 12th, 2016 at 14:53 | #14

    [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

  15. Faye
    August 24th, 2016 at 17:00 | #15

    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]

Comments are closed.