linux实际使用内存比used少,Linux Used内存到底哪里去了?

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

前几天 纯上 同窗问了一个问题:bash

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

这个问题不止一个同窗遇到过了,以前子嘉同窗也遇到这个问题,内存的计算老是一个迷糊帐。 咱们今天来把它算个清楚下!ide

一般咱们是这样看内存的剩余状况的:wordpress

$free -m

total       usedfree     shared    buffers     cached

Mem:         48262       7913      40349          0         14        267

-/+ buffers/cache:       7631      40631

Swap:         2047        336       1711

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

902a81bbeaa6ec0b0ca87741ec09f63f.png工具

补充(很多人反映图不清晰,请参考:http://www.redbooks.ibm.com/redpapers/pdfs/redp4285.pdf P46-47)post

上面的状况下咱们总的内存有48262M,用掉了7913M。 其中buffer+cache总共14+267=281M, 因为这种类型的内存是能够回收的,虽然咱们用掉了7913M,可是实际上咱们若是实在须要的话,这部分buffer/cache内存是能够放出来的。性能

咱们来演示下:url

$sudo sysctl vm.drop_caches=3

vm.drop_caches = 3

$free -m

total       usedfree     shared    buffers     cached

Mem:         48262       7676      40586          0          3         41

-/+ buffers/cache:       7631      40631

Swap:         2047        336       1711

咱们把buffer/cache大部分都清除干净了,只用了44M,因此咱们此次used的空间是7676M。

到如今咱们比较清楚几个概念:

1. 总的内存多少

2. buffer/cache内存能够释放的。

3. used的内存的几率。

即便是这样咱们仍是要继续追查下used的空间(7637M)到底用到哪里去了?

这里首先咱们来介绍下nmon这个工具,它对内存的使用显示比较直观。

9f5deb683cbc0bf3759aa35879429ee2.png

使用的内存的去向咱们很天然的就想到操做系统系统上的各类进程须要消耗各类内存,咱们透过top工具来看下:

324303940828cb8eb3adef4fb43f98d9.png

一般咱们会看进程的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]/statm

Provides information about memory usage, measured in pages. The

columns 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 + stack

dt dirty pages (unused in Linux 2.6)

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

咱们实际进程使用的物理页面应该用resident set size来算的,遍历全部的进程,就能够知道全部的全部的进程使用的内存。

咱们来实验下RSS的使用状况:

$cat RSS.sh

#/bin/bash

for PROCin `ls  /proc/|grep "^[0-9]"`

do

if [ -f /proc/$PROC/statm ];then

TEP=`cat /proc/$PROC/statm |awk '{print ($2)}'`

RSS=`expr $RSS + $TEP`

fi

done

RSS=`expr $RSS \* 4`

echo $RSS"KB"

$ ./RSS.sh

7024692KB

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

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

0ba10c0a166ca3c7eedfa0697958d179.png

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

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

$ slabtop

咱们能够看到:

ea19afa935136bf47870848840103a8e.png

从图咱们能够看出各类对象的大小和数目,遗憾的是没有告诉咱们slab消耗了多少内存。

咱们本身来算下好了:

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

904.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}'` KB

58052 KB

好吧,小结下!内存的去向主要有3个:1. 进程消耗。 2. slab消耗 3.pagetable消耗。

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

$cat cm.sh

#/bin/bash

for PROCin `ls /proc/|grep "^[0-9]"`

do

if [ -f /proc/$PROC/statm ];then

TEP=`cat /proc/$PROC/statm |awk '{print ($2)}'`

RSS=`expr $RSS + $TEP`

fi

done

RSS=`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.sh

7003756KB, 59272KB, 904.334MB

rss+pagetable+slabinfo=7800.334MB

total       usedfree     shared    buffers     cached

Mem:         48262       8050      40211          0         17        404

-/+ buffers/cache:       7629      40633

Swap:         2047        336       1711

free报告说7629M, 咱们的cm脚本报告说7800.3M, 咱们的CM多报了171M。

damn,这又怎么回事呢?

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

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

$ pmap `pgrepbash`

...

22923:   -bash

0000000000400000    848K r-x--  /bin/bash

00000000006d3000     40K rw---  /bin/bash

00000000006dd000     20K rw---    [ anon ]

00000000008dc000     36K rw---  /bin/bash

00000000013c8000    592K rw---    [ anon ]

000000335c400000    116K r-x--  /lib64/libtinfo.so.5.7

...

0000003ec5220000      4K rw---  /lib64/ld-2.12.so

0000003ec5221000      4K rw---    [ anon ]

0000003ec5800000   1628K r-x--  /lib64/libc-2.12.so

...

0000003ec5b9c000     20K rw---    [ anon ]

00007f331b910000  96836K r----  /usr/lib/locale/locale-archive

00007f33217a1000     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.cache

00007f33219c8000      4K rw---    [ anon ]

00007fff5e553000     84K rw---    [ stack ]

00007fff5e5e4000      4K r-x--    [ anon ]

ffffffffff600000      4K r-x--    [ anon ]

total           108720K

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

可是因为每一个进程共享的东西都不同,咱们也无法知道每一个进程是如何共享的,无法作到准确的区分。

因此只能留点小遗憾,欢迎你们来探讨。

总结:内存方面的概念不少,须要深刻挖掘!

祝玩的开心!

Post Footer automatically generated by wp-posturl plugin for wordpress.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值