转载:Linux Used内存到底到哪里去了?
转自:http://blogread.cn/it/article/6264?f=wb2
有时在Linux下会碰到这样的问题:ps aux看到的RSS内存只有不到30M,但是free看到内存却已经使用了7、8G了,已经开始swap了,这是怎么回事?
通常我们查看系统内存都是用free命令:
$free -m
              total       used       free     shared    buffers     cached
Mem:          2010       1721        289          7         99        606
-/+ buffers/cache:       1015        995
Swap:         3904          0       3904
如何解读输出的这些信息呢?下面这个图看的挺清楚:

图中内存总共4092M,用掉了3270M,其中buffers+cached是36+1482=1518M,这部分内存是可以回收的,如果需要的话,可以释放出来,这样用掉的内存就是3270-1518=1752M,由于会有一部分计算和系统的耗费,这个值是1748M。
释放缓存:
$ sudo sysctl vm.drop_caches=3
vm.drop_caches = 3
$ free -m
             total       used       free     shared    buffers     cached
Mem:         48262       7676      40586          0          3         41
-/+ buffers/cache:       7631      40631
Swap:         2047        336       1711
或者:
#free -m
              total       used       free     shared    buffers     cached
Mem:          2010       1742        268          8        100        608
-/+ buffers/cache:       1033        976
Swap:         3904          0       3904
#echo 1 > /drop/sys/vm/drop_caches
#free -m
             total       used       free     shared    buffers     cached
Mem:          2010       1204        806          8          0        162
-/+ buffers/cache:       1041        969
Swap:         3904          0       3904
现在清楚了几个概念:
- 总的内存是多少
- buffer/cache内存可以释放
- used内存的概率
下面就要追查以下used的空间到底去哪儿了。
首先介绍nmon这份工具,它对内存的使用显示比较直观:

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

通常我们会看进程的RES这一项,这项到底是什么意思呢?这个数字从哪里出来的呢? 通过strace对top和nmon的追踪和结合源码,我们确定这个值是从/proc/PID/statm的第二个字段读取出来的.
    /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的使用情况:
#! /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`
    fi
done
RSS=`expr $RSS \* 4`
echo $RSS"KB"
从数字来看,我们的进程使用了大概7024M内存,距离7637M还有几百M内存哪里去了? 哪里去了?
仔细看一下nmon的内存统计表:

slab又是什么?PageTable又是什么?
简单的说内核为了高性能每个需要重复使用的对象都会有个池,这个slab池会cache大量常用的对象,所以会消耗大量的内存。运行命令:
$slabtop
可以看到

虽然没有给出,但给出了具体情况,可以自己算:
$echo `cat /proc/slabinfo | awk 'BEGIN{sum=0;} {sum=sum+$3*$4;}END{print sum/1024/1024}'`MB
904.256 MB
PageTables呢?
struct page是系统boot的时候就会根据内存大小算出来分配出去的,18内核是1.56%左右,32内核由于cgroup的原因会在2.3%
$echo `grep PageTables /proc/meminfo | awk '{print $2}'` KB
58052 KB
小结
内存的去向主要有3个:
- 进程消耗
- slab消耗
- pagetable消耗
汇总一下:
#/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`
    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       used       free     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。
我们重新校对下我们的计算。 我们和nmon来比对下,slab和pagetable的值是吻合的。 那最大的问题可能在进程的消耗计算上。
resident resident set size 包括我们使用的各种库和so等共享的模块,在前面的计算中我们重复计算了。
转载:Linux Used内存到底到哪里去了?的更多相关文章
- Linux Used内存到底哪里去了?
		原创文章,转载请注明: 转载自系统技术非业余研究 本文链接地址: Linux Used内存到底哪里去了? 前几天 纯上 同学问了一个问题: 我ps aux看到的RSS内存只有不到30M,但是free看 ... 
- <转载>linux下内存泄露查找、BUG调试
		先收藏着,抽空好好看看:http://www.ibm.com/developerworks/cn/linux/l-pow-debug/ 简介 调试程序有很多方法,例如向屏幕上打印消息,使用调试器,或者 ... 
- 转 linux进程内存到底怎么看 剖析top命令显示的VIRT RES SHR值
		引 言: top命令作为Linux下最常用的性能分析工具之一,可以监控.收集进程的CPU.IO.内存使用情况.比如我们可以通过top命令获得一个进程使用了多少虚拟内存(VIRT).物理内存(RES). ... 
- linux进程内存到底怎么看 剖析top命令显示的VIRT RES SHR值
		引 言: top命令作为Linux下最常用的性能分析工具之一,可以监控.收集进程的CPU.IO.内存使用情况.比如我们可以通过top命令获得一个进程使用了多少虚拟内存(VIRT).物理内存(RES). ... 
- Linux内核内存管理算法Buddy和Slab: /proc/meminfo、/proc/buddyinfo、/proc/slabinfo
		slabtop cat /proc/slabinfo # name <active_objs> <num_objs> <objsize> <objpersla ... 
- 查看linux的进程到底用了多少内存
		1. 在linux下,查看一个运行中的程序, 占用了多少内存, 一般的命令有 (1). ps aux: 其中 VSZ(或VSS)列 表示,程序占用了多少虚拟内存. ... 
- Linux的内存机制(转载)
		今天我们来谈谈Linux的内存机制. 首先我们理一下概念 一.什么是linux的内存机制? 我们知道,直接从物理内存读写数据要比从硬盘读写数据要快的多,因此,我们希望所有数据的读取和写入都在内存完成, ... 
- [转载]Linux内存高,触发oom-killer问题解决
		最近遇到两起Linux的内存问题,其一是触发了oom-killer导致系统挂 首先确认该系统的版本是32位 #uname -a Linux alarm 2.6.9-67.ELsmp #1 SMP We ... 
- Linux就这个范儿 第15章 七种武器  linux 同步IO: sync、fsync与fdatasync   Linux中的内存大页面huge page/large page  David Cutler  Linux读写内存数据的三种方式
		Linux就这个范儿 第15章 七种武器 linux 同步IO: sync.fsync与fdatasync Linux中的内存大页面huge page/large page David Cut ... 
随机推荐
- Cocos3d-x 发布第一版
			从去年开始11一月,我开始一个又一个人cocos3d的C++改写版本号.现在见效.所有cocos3d的OC代码改写成了C++. 在正常Android和Windows在执行.上周,正式发布了第一个版本. ... 
- ASP.NET MVC:01理解MVC模式
			ASP.NET MVC是ASP.NET Web应用程序框架,以MVC模式为基础. MVC:Model View Controller 模型-视图-控制器Model(模型):负责对数据库的存取View( ... 
- atitit.基于组件的事件为基础的编程模型--服务器端控件(1)---------服务器端控件和标签之间的关系
			atitit.基于组件的事件为基础的编程模型--服务器端控件(1)---------服务器端控件和标签之间的关系 1. server控件是要server了解了标签.种类型的server控件: 1 1. ... 
- Swift: 打造滑动解锁文字动画
			原文:Swift: 打造滑动解锁文字动画 最近木事,找出来玩了玩facebook的paper.到处都是那个"slide to unlock your phone"的效果啊.忽闪忽闪 ... 
- 数组、链表、Hash(转)
			在程序中,存放指定的数据最常用的数据结构有两种:数组和链表. 数组和链表的区别: 1.数组是将元素在内存中连续存放. 链表中的元素在内存中不是顺序存储的,而是通过存在元素中的指针联系到一起. 2.数组 ... 
- 使用C++实现功能下载文件
			今天问一个同学C++实现的下载链接下载并保存给定的文件,互联网搜索.看到这样的事情在网上.因此,改变下直接带来,因为他的代码是在VC++,我导入到VS2010中出现点小问题.所以改了下贴了个VS中亲測 ... 
- android使用ffmpeg
			cygwin上文编译文章. 在ffmpeg/arm添加的文件夹Android.mk 的主要目的是为了宣布动态库libs下一个 LOCAL_PATH:= $(call my-dir) include $ ... 
- Asp.net .net(C#) 获取当前命名空间,类名,方法名的方法
			public static string GetMethodInfo() { string str = ""; //取得当前方法命名空间 str += & ... 
- String.Split()功能
			我们在过去的教训 String.Join功能(http://blog.csdn.net/zhvsby/archive/2008/11/28/3404704.aspx).当中用到了String.SPli ... 
- 《python源代码分析》笔记 pythonVM一般表达式
			本文senlie原版的.转载请保留此地址:http://blog.csdn.net/zhengsenlie 1.字节码指令 LOAD_CONST:从consts表中读取序号为i的元素并压入到执行时栈中 ... 
