Linux used内存到底去哪里了呢?

阅读文章之前请先思考这么个问题

我ps aux看到的RSS内存只有不到30M,但是free看到内存却已经使用了7,8G了,已经开始swap了,请问ps aux的实际物理内存统计是不是漏了哪些内存没算?我有什么办法确定free中used的内存都去哪儿了呢?

这个问题不止一个同学遇到过了,内存的计算总是一个迷糊账。我们今天来把它算个清楚下!

通常我们是这样看内存的剩余情况的:

$free -m             total       used       free     shared    buffers     cachedMem:         48262       7913      40349          0         14        267-/+ buffers/cache:       7631      40631Swap:         2047        336       1711

那么这个信息是如何解读的呢,以下这个图解释的挺清楚的!

img

上面的情况下我们总的内存有48262M,用掉了7913M。其中buffer+cache总共14+267=281M, 由于这种类型的内存是可以回收的,虽然我们用掉了7913M,但是实际上我们如果实在需要的话,这部分buffer/cache内存是可以放出来的。

我们来演示下:

$ sudo sysctl vm.drop_caches=3vm.drop_caches = 3$ free -m             total       used       free     shared    buffers     cachedMem:         48262       7676      40586          0          3         41-/+ buffers/cache:       7631      40631Swap:         2047        336       1711

我们把buffer/cache大部分都清除干净了,只用了44M,所以我们这次used的空间是7676M。到现在我们比较清楚几个概念:

1. 总的内存多少2. buffer/cache内存可以释放的。3. used的内存的概率。

即使是这样我们还是要继续追查下used的空间(7637M)到底用到哪里去了?这里首先我们来介绍下nmon这个工具,它对内存的使用显示比较直观。

img

使用的内存的去向我们很自然的就想到操作系统系统上的各种进程需要消耗各种内存,我们透过top工具来看下:

img

通常我们会看进程的RES这一项,这项到底是什么意思呢?这个数字从哪里出来的呢?通过strace对top和nmon的追踪和结合源码,我们确定这个值是从/proc/PID/statm的第二个字段读取出来的。

那这个字段什么意思呢?man proc

或者http://www.kernel.org/doc/man-pages/online/pages/man5/proc.5.html 会详细的解释/proc/下的文件的具体意思,我们摘抄下:

/proc/[pid]/statmProvides information about memory usage, measured in pages. Thecolumns are:

size total program size(same as VmSize in /proc/[pid]/status)resident resident set size(same as VmRSS in /proc/[pid]/status)share shared pages (from shared mappings)text text (code)lib library (unused in Linux 2.6)data data + stackdt dirty pages (unused in Linux 2.6)

resident set size 也就是每个进程用了具体的多少页的内存。由于linux系统采用的是虚拟内存,进程的代码,库,堆和栈使用的内存都会消耗内存,但是申请出来的内存,只要没真正touch过,是不算的,因为没有真正为之分配物理页面。

我们实际进程使用的物理页面应该用resident set size来算的,遍历所有的进程,就可以知道所有的所有的进程使用的内存。

我们来实验下RSS的使用情况:

$ cat RSS.sh#/bin/bash                                                                                                               for PROC in `ls  /proc/|grep "^[0-9]"`do  if [ -f /proc/$PROC/statm ]; then      TEP=`cat /proc/$PROC/statm | awk '{print ($2)}'`      RSS=`expr $RSS + $TEP`  fidoneRSS=`expr $RSS \* 4`echo $RSS"KB"$ ./RSS.sh  7024692KB

从数字来看,我们的进程使用了大概7024M内存,距离7637M还有几百M内存哪里去了?哪里去了?猫吃掉了?

我们再回头来仔细看下nmon的内存统计表。

img

那个该死的slab是什么呢?那个PageTables又是什么呢?

简单的说内核为了高性能每个需要重复使用的对象都会有个池,这个slab池会cache大量常用的对象,所以会消耗大量的内存。运行命令:

$ slabtop

我们可以看到:

img

从图我们可以看出各种对象的大小和数目,遗憾的是没有告诉我们slab消耗了多少内存。

我们自己来算下好了:

$ echo `cat /proc/slabinfo |awk 'BEGIN{sum=0;}{sum=sum+$3*$4;}END{print sum/1024/1024}'` MB904.256 MB

好吧,把每个对象的数目*大小,再累加,我们就得到了总的内存消耗量:904M

那么PageTables呢?我们万能的内核组的同学现身了:

伯瑜:你还没有计算page tables的大小,还有struct page也有一定的大小(每个页一个,64bytes),如果是2.6.32的话,每个页还有一个page_cgroup(32bytes),也就是说内存大小的2.3%(96/4096)会被内核固定使用的含黛:struct page是系统boot的时候就会根据内存大小算出来分配出去的,18内核是1.56%左右,32内核由于cgroup的原因会在2.3%

好吧,知道是干嘛的啦,管理这些物理页面的硬开销,那么具体是多少呢?

$ echo `grep PageTables /proc/meminfo | awk '{print $2}'` KB58052 KB

好吧,小结下!内存的去向主要有3个:

  • \1. 进程消耗。
  • \2. slab消耗
  • 3.pagetable消耗。

我把三种消耗汇总下和free出的结果比对下,这个脚本的各种计算项仲同学帮忙搞定的:

$ cat cm.sh#/bin/bashfor PROC in `ls /proc/|grep "^[0-9]"`do  if [ -f /proc/$PROC/statm ]; then      TEP=`cat /proc/$PROC/statm | awk '{print ($2)}'`      RSS=`expr $RSS + $TEP`  fidoneRSS=`expr $RSS \* 4`PageTable=`grep PageTables /proc/meminfo | awk '{print $2}'`SlabInfo=`cat /proc/slabinfo |awk 'BEGIN{sum=0;}{sum=sum+$3*$4;}END{print sum/1024/1024}'`

echo $RSS"KB", $PageTable"KB", $SlabInfo"MB"printf "rss+pagetable+slabinfo=%sMB\n" `echo $RSS/1024 + $PageTable/1024 + $SlabInfo|bc`free -m

$ ./cm.sh7003756KB, 59272KB, 904.334MBrss+pagetable+slabinfo=7800.334MB             total       used       free     shared    buffers     cachedMem:         48262       8050      40211          0         17        404-/+ buffers/cache:       7629      40633Swap:         2047        336       1711free报告说7629, 我们的cm脚本报告说7800.3M, 我们的CM多报了171M。damn,这又怎么回事呢?

我们重新校对下我们的计算。我们和nmon来比对下,slab和pagetable的值是吻合的。那最大的问题可能在进程的消耗计算上。

resident  resident set size 包括我们使用的各种库和so等共享的模块,在前面的计算中我们重复计算了。

$ pmap `pgrep bash`...22923:   -bash0000000000400000    848K r-x--  /bin/bash00000000006d3000     40K rw---  /bin/bash00000000006dd000     20K rw---    [ anon ]00000000008dc000     36K rw---  /bin/bash00000000013c8000    592K rw---    [ anon ]000000335c400000    116K r-x--  /lib64/libtinfo.so.5.7...0000003ec5220000      4K rw---  /lib64/ld-2.12.so0000003ec5221000      4K rw---    [ anon ]0000003ec5800000   1628K r-x--  /lib64/libc-2.12.so...0000003ec5b9c000     20K rw---    [ anon ]00007f331b910000  96836K r----  /usr/lib/locale/locale-archive00007f33217a1000     48K r-x--  /lib64/libnss_files-2.12.so...00007f33219af000     12K rw---    [ anon ]00007f33219bf000      8K rw---    [ anon ]00007f33219c1000     28K r--s-  /usr/lib64/gconv/gconv-modules.cache00007f33219c8000      4K rw---    [ anon ]00007fff5e553000     84K rw---    [ stack ]00007fff5e5e4000      4K r-x--    [ anon ]ffffffffff600000      4K r-x--    [ anon ] total           108720K

多出的171M正是共享库重复计算的部分。

但是由于每个进程共享的东西都不一样,我们也没法知道每个进程是如何共享的,没法做到准确的区分。

总结:内存方面的概念很多,需要深入挖掘!

作者:Yu Feng 链接:http://blog.yufeng.info/archives/245

值从哪里来_Linux used内存到底去哪里了呢?相关推荐

  1. Linux Used内存到底哪里去了?

    原创文章,转载请注明: 转载自系统技术非业余研究 本文链接地址: Linux Used内存到底哪里去了? 前几天 纯上 同学问了一个问题: 我ps aux看到的RSS内存只有不到30M,但是free看 ...

  2. 去重之后统计条数_BOPET:12的普通包装膜到底去哪了?

    导语 近期BOPET市场多数客户反映,12μ的普通包装膜现货一货难求,前期订单交货紧张,新订单交期较长,12μ的普通包装膜到底去哪了呢? 对于BOPET市场来说,12μ普通包装膜交货紧.交货慢的现象从 ...

  3. OSChina 周五乱弹 —— 那地图上的点到底去哪儿

    2019独角兽企业重金招聘Python工程师标准>>> Osc乱弹歌单(2018)请戳(这里) [今日歌曲] @莱布妮子 :分享高橋洋子的单曲<残酷な天使のテーゼ> &l ...

  4. STL——空间配置器剖析(一级空间配置器、二级空间配置器的本质及运用场合,是如何用内存池去管理的)

    一级空间配置器.二级空间配置器的本质及运用场合,是如何用内存池去管理的 研究了好久才写好的,主要是二级配置器,大标题小标题什么的可能没有安排好,先 写了原理上的内容,再剖析了各个函数源码,各个目录可以 ...

  5. 五一2.74亿人倾巢而出,小长假到底去哪玩儿?

    今天是五一劳动节小长假结束后,打工人上班的第一天. 今年的五一非比寻常,是三年口罩之后的第一个小长假,回家探亲的回家.出门玩的出门,据统计,今年五一劳动节5天小长假,累计有2.74亿人次在国内出游,同 ...

  6. 转 linux进程内存到底怎么看 剖析top命令显示的VIRT RES SHR值

    引 言: top命令作为Linux下最常用的性能分析工具之一,可以监控.收集进程的CPU.IO.内存使用情况.比如我们可以通过top命令获得一个进程使用了多少虚拟内存(VIRT).物理内存(RES). ...

  7. 值传递和引用传递传的到底是啥?

    作者 | 编程指北  责编 | 张文 来源 | 编程指北(ID:cs_dev) 在网上看到过很多讨论 Java.C++.Python 是值传递还是引用传递这类文章,所以这一篇呢就是想从原理讲明白关于函 ...

  8. ddr4 dqs 频率_高频DDR4内存到底有啥优势?除了贵啥都好

    内存是CPU与硬盘之间的桥梁.高性能CPU.SSD,依赖内存的高性能表现.而影响内存性能最直接的因素---"频率"!原则上,频率越高,内存性能越强.(当然,这也不是绝对的,内存时序 ...

  9. 程序员交流平台_Java虚拟机所管理的内存到底有哪些?Java程序员必看栏目(上)...

    Java虚拟机所管理的内存将会包括以下几个运行时数据区域: 1,程序计数器Program Counter Register 一块较小的内存空间,非所有线程共享的区域,每个程序计数器,都会记录当前线程执 ...

最新文章

  1. 24个提高知识和技能极限的机器学习项目
  2. Stucts应用引起的OutOfMemoryError
  3. LINQ to Entities 基于方法的查询语法
  4. currentdate mysql_Mysql】Mysql中CURRENT_TIMESTAMP,CURRENT_DATE,CURRENT_TIME,now(),sysdate()各项值的区别...
  5. 记录安装mysql5.7.24遇到的坑
  6. [转]Android中pendingIntent的深入理解
  7. python中的常量可以修改吗_python实现不可修改的常量
  8. hdu 1176:免费馅饼
  9. Qt——P26 Label控件显示图片
  10. python最适合做什么-python适合做什么开发_python未来发展怎么样
  11. paip.python错误解决19
  12. 多尺度图像增强Retinex相关算法学习及实现
  13. PHP for windows VC9 VC6区别
  14. 初、中、高级程序员的区别有哪些
  15. yii 进入后台 inex.php,PHP应用:Yii中实现处理前后台登录的新方法
  16. IOS学习笔记-加速度传感器(重力感应)-UIAccelerometer
  17. Python生成器详解(自定义的迭代器)
  18. 声网发布极速直播、低码高清 首创轻互动直播,节省50%带宽成本
  19. 今天我被微软狠狠地雷翻了
  20. 规范化理论:范式等级

热门文章

  1. (转)在Myeclipse中查看android源码就是这么easy
  2. 计算机网络df例题,计算机网络期末试题北交.doc
  3. 高级语言程序设计c 华南理工,华南理工大学高级语言程序设计(C)期末练习题
  4. switch芯片和phy芯片的区别_感应式芯片卡CPU卡的FM1208-9和FM1208-10有什么区别,你知道吗?...
  5. Maven基础及概念
  6. 如何解决ajax跨域问题
  7. concat特征融合_MSFNet:多重空间融合网络进行实时语义分割(北航和旷视联合提出)...
  8. python京东商品_Python爬取京东的商品分类与链接
  9. hexeditor 复制二进制值_MySQL复制全解析 Part 6 MySQL GTID 生命周期
  10. [转载] 手把手教你整合最优雅SSM框架:SpringMVC + Spring + MyBatis