目录

linux查看内存通用命令

命令1:free -h

命令2:cat /proc/PID/status

命令3:cat /proc/PID/maps

命令4:cat /proc/PID/smaps

对于内存的检测提供两个脚本方案:

对全部进程进行内存统计

对特定模块进行内存统计


linux查看内存通用命令

命令1:free -h

输出结果如下:

 描述信息分为两行,Mem(内存相关描述)和Swap(交换分区相关描述)。通常在嵌入式上不使用Swap分区,所以不进行论述

项目名

数值

意义

Total

1.2G

系统物理内存总量 1.2G

Used

769M

表示总计分配给缓存(包含buffers与cach)使用的大小为769M,但其中可能有部分缓存并未实际使用。

Free

347M

系统剩余总量347M

Shared

12M

共享内存12M

Buff/cache

137M

统称缓冲区137M,区别如下:

写如磁盘时,先保存到磁盘缓冲区(buffer),然后再写入到磁盘。

磁盘读出后,暂留在缓冲区(cache),为后续程序的使用做准备。

available

405M

Free是指真正未使用的物理内存量,available是从程序角度可以看到的可用的内存数量。程序角度认为,未使用的内存和缓冲区都可以用来使用,所以理论上available=free+buff+cache,但这是一个理想的计算方法。实际上会有一些偏差

通常,需要使用free -h命令对整体内存进行判断。如果free一直在下降或used一直在上升则认为内存存在泄漏。

命令2:cat /proc/PID/status

输出结果如下:

Status下会有很多进程描述信息,但对于内存仅需要关注红框中内容即可

项目名

数值

意义

VmPeak

399256kB

是当前进程使用的虚拟内存的峰值

VmSize

333860kB

是当前进程实时虚拟内存使用情况

VmHWM

7628kB

是当前进程使用的物理内存的峰值

VmRSS

7628kB

是当前进程实时物理内存使用情况

RssAnon

4692kB

当前进程使用的匿名内存大小

RssFile

2936kB

当前进程文件使用内存大小

RssShmem

0kB

当前进程共享内存大小

VmData

67056kB

是当前进程数据段的大小

VmStk

132kB

是当前进程堆栈段的大小

VmExe

8kB

是当前进程代码段的大小

VmLib

4472kB

是当前进程使用的LIB库的大小

针对内存问题的检证,首先要确认VmSize和VmRSS的变化情况确认来是否有内存泄漏。如果出现泄漏则需要观察其他项目来判断是哪里出现了问题。

命令3:cat /proc/PID/maps

首先,要理解在Linux上,系统会对每个进行分配8G(默认设定)的虚拟空间。本命令是对当前进程的虚拟内存的具体分配结果(简略信息)。

输出的结果中会包含栈信息,堆信息,已经使用了哪些库。如下图。

命令4:cat /proc/PID/smaps

本命令是对命令3 的详细描述,会对每一具体分配段进行详细的数据展开,如下图

对于每一段的数据都会有上图所示信息,但仅需要关注红框部分信息即可,有四个关键字段 Rss 和Pss ,shared 和Private

项目名

数值

意义

Rss

8kB

是进程的物理内存占用,包括进程本身和所有链接库,RSS = private + share

Pss

8kB

链接库的共享内存平摊计算后的使用内存,(比如一个动态库有5个人引用,则将其代码段和共享内存除于5),PSS = private + share

Shared_Clean

0kB

和其他进程共享的未改写页面

Shared_Dirty

0kB

和其他进程共享的已改写页面

Private_Clean

0kB

未改写的私有页面页面

Private_Dirty

8kB

已改写的私有页面页面

其中: private = private_clean + private_dirty: 这个数据一般能够比较准确反映一个进程内部占用的内存,在内存优化的时候使用这个作为参考值比较合理,进程的物理内存占用就是smaps中所有的private的相加(链接的动态库的也要统计进去)。

仅仅你自己使用的库 是属于Private的,如果别人也用这个库 则是属于Shared。当然你的代码如果链接给别人,也是属于Shared。

所以想要得到确定的内存使用量,将/proc/PID/smap中的所有Private_Clean和Private_Dirty累加起来,是很好的解决方案

对于内存的检测提供两个脚本方案:

对全部进程进行内存统计

检测全部进程内存量的脚本,(输出时通过 ] 符号进行分割,方便用excel进行分列数据统计)

#!/bin/bash


a=1
 echo "8 > /proc/sys/kernel/printk" 
while [ $a -eq 1 ];do
 
echo "########################"
echo `date "+%Y-%m-%d %H:%M:%S"`


echo "free"
free -h

for pid in `ls -1 /proc/ | egrep "[[:digit:]]"`; 
do if [ -f "/proc/$pid/status" ]; 
	then proc_name=`grep '^Name' /proc/$pid/status | awk '{print $2}'`; 
	mem_VmPeak=`grep '^VmPeak' /proc/$pid/status | awk '{print $2}'`; 
	mem_VmRSS=`grep '^VmRSS' /proc/$pid/status | awk '{print $2}'`;
	mem_VmSize=`grep '^VmSize' /proc/$pid/status | awk '{print $2}'`;
	mem_VmData=`grep '^VmData' /proc/$pid/status | awk '{print $2}'`;
	if [[ $mem_VmPeak != "" ]]; then echo "]$proc_name] VmPeak : ]$mem_VmPeak] kB VmRSS : ]$mem_VmRSS] kB VmSize : ]$mem_VmSize] kB VmData : ]$mem_VmData] kB";
	fi
 fi
 done



 echo "########################"
 sleep 30s
 done

对特定模块进行内存统计

当确认是某一个模块的问题时,在通过下面的脚本对单独的模块进行内存统计

(下面的脚本中替换loggmr为想调查的进程名即可)

#!/bin/bash
while [ 1 -eq 1 ];do
echo "########################"
echo `date "+%Y-%m-%d %H:%M:%S"`
free
pid=$(ps -aux |grep logmgr|head -n 1|awk '{print $2}')
echo "++++++++++++++++++++"
echo RssSum_SUM:`cat /proc/$pid/smaps |grep Rss|awk 'BEGIN{sum=0;}{sum=sum+$2;}END{print sum}'`KB
echo PssSum_SUM:`cat /proc/$pid/smaps |grep Pss|awk 'BEGIN{sum=0;}{sum=sum+$2;}END{print sum}'`KB
echo Shared_Clean_SUM:`cat /proc/$pid/smaps |grep Shared_Clean|awk 'BEGIN{sum=0;}{sum=sum+$2;}END{print sum}'`KB
echo Shared_Dirty_SUM:`cat /proc/$pid/smaps |grep Shared_Dirty|awk 'BEGIN{sum=0;}{sum=sum+$2;}END{print sum}'`KB
echo Private_Clean_SUM:`cat /proc/$pid/smaps |grep Private_Clean|awk 'BEGIN{sum=0;}{sum=sum+$2;}END{print sum}'`KB
echo Private_Dirty_SUM:`cat /proc/$pid/smaps |grep Private_Dirty|awk 'BEGIN{sum=0;}{sum=sum+$2;}END{print sum}'`KB
echo "-----------------------"
cat /proc/$pid/status

sleep 30s
done

 

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐