一个经常被问的Linux问题:为啥我的Linux系统没运行多少程序,显示的可用内存这么少?其实Linux与Win的内存管理不同,会尽量缓存内存以提高读写性能,通常叫做Cache Memory。
比较老的文件都会介绍Linux的cache占用很多没关系,因为Linux尽可能利用内存进行缓存,但是缓存的回收也是需要资源的,比较好的一篇文章是Poor Zorro写的Linux内存中的Cache真的能被回收么?。
虽然大部分情况下我们看到cache很高没有问题,但是我们还是想弄清楚到底是哪个程序把cache弄的那么高,这居然不是一件容易的事。
内核的模块在分配资源的时候,为了提高效率和资源的利用率,都是透过slab来分配的。slab为结构性缓存占用内存,该项也经常占用很大的内存。不过借助slabtop工具,我们可以很方便的显示内核片缓存信息,该工具可以更直观的显示/proc/slabinfo下的内容。
slabtop -s c
显示了一台机器缓存中占用对象的情况:
|
|
虽然上面的命令现实了cache中slab的情况,但是还是没有显示什么程序占用的cache。
linux-ftools这个工具可以显示某个文件占用的cache的情况, fincore是它其中的一个工具:
|
|
fincore的工作原理是将指定的文件的相应inode data与kernel的 page cache table做对比,如果page cache table有这个inode 信息,就找该inode对应的data block的大小。因为kernel的page cache table只存储data block的引用而不是文件名,即文件的inode信息。所以并没有任何一个工具运行一次就可以找出所有的文件使用缓存的情况。
所以使用linux-fincore只能加文件名,来判断该文件是否被缓存,如果缓存,大小是多少。问题是你不能随便猜哪个文件是否被缓存吧。
shanker提供了一个办法,那就查看哪些进程使用的物理内存最多,就找到该进程打开的文件,然后用fincore查看这些文件的缓存使用率。
这个办法在大部分情况下都可以找到占用cache较多的程序和进程。
他的这个脚本如下:
|
|
比较遗憾的是,linux-ftools看起来不再维护了。我在我的服务器也没有编译好这个程序,所以还得想办法。
后来找到pcstat这个工具,功能和linux-ftools一样,使用Go开发。
然后我修改了Shanker的脚本,让它使用pcstat进行处理,可以很好的找到cache占用的情况。
修改的脚本如下:
|
|
显示结果:
|
|
可以看到 uuid.log占用cache比较多。我的程序中这个文件是打开的,一直往里面写日志,Linux应该是把它缓存了。
参考文档
- https://code.google.com/p/linux-ftools/
- https://github.com/tobert/pcstat
- http://shanker.blog.51cto.com/1189689/1787378
- http://www.linuxatemyram.com
- http://colobu.com/2015/10/31/How-to-Clear-RAM-Memory-Cache-Buffer-and-Swap-Space-on-Linux/
- http://liwei.life/2016/04/26/linux内存中的cache真的能被回收么?/