top 命令可列出各个进程对系统资源的利用情况。其中有 VIRT, RES, SHR, CODE, DATA 等几个字段,用来描述进程对内存的使用情况。(后二者默认不展示,需要按下 F 键,将相关字段调出来)。

top virt
VIRT Virtual Memory Size (KiB):进程使用的所有虚拟内存;包括代码(code)、数据(data)、共享库(shared libraries),以及被换出(swap out)到交换区和映射了(map)但尚未使用(未载入实体内存)的部分。

top res
RES Resident Memory Size (KiB):进程所占用的所有实体内存(physical memory),不包括被换出到交换区的部分。

top shr
SHR Shared Memory Size (KiB):进程可读的全部共享内存,并非所有部分都包含在 RES 中。它反映了可能被其他进程共享的内存部分。
top code
CODE Code Size (KiB):进程所占用的实体内存中,可执行代码所占用的内存大小。此项亦称为驻存代码集合(Text Resident Set, TRS)。
top data
DATA Data + Stack Size (KiB):进程所占用的实体内存中,除去可执行代码所占用部分之外的内存大小。此项亦称为驻存数据集合(Data Resident Set, DRS)。

top 命令的数据源
top 命令读取的是 /proc/<pid>/statm 当中的数据。

你可以通过 cat /proc/<pid>/statm 来查看。它有 7 列,分别是以内存页计算的 VIRT, RES, SHR, CODE, LRS, DATA, DIRTY。其中 LRS 和 DIRTY 自 Linux 2.6 开始不再使用。内存页的大小是 4KiB,因此,将内存页的数量乘以 4,就是以 KiB 计算的内存占用大小。
top 内存泄漏
如果观察到程序稳定运行时 RES - SHR 不断增长,则可能预示着程序存在内存泄漏现象。

top 内存泄漏 分析解决步骤
A、第一次分析与处理
现象:%MEM 字段 ,进程使用的物理内存百分比 与 VIRT 字段,进程使用的虚拟内存总量,均随运行时间不断增加

分析: 明显的发生了内存泄漏,很容易想到new的数据是否delete。通过分析 问题出在 其他人的 数据模拟模块相关代码中:new 的数据没有delete掉。

优化: 于是优化相关代码后再次验证,确保所有new的数据均得到正确的delete,也包括malloc申请的空间也得到正确的free。

B、第二次分析与处理
现象: 再次通过top命令采集数据, %MEM 字段 ,进程使用的物理内存百分比 与 RES 字段进程使用的、未被换出的物理内存大小 不再增加 , 但是VIRT 字段,进程使用的虚拟内存总量还是在不断增加

分析: %MEM 字段 与 RES 字段 不再增加说明第一次分析与处理的效果是有的。继续计算出VIRT字段数据每次增加的量,发现每次增加的是一个固定值。

比较下 实存(RES) 与 虚存(VIRT) 具体包括什么:

VIRT: 进程“需要的”虚拟内存大小,包括进程使用的库、代码、数据,以及malloc、new分配的堆空间和分配的栈空间等;

RES: 进程当前使用的内存大小,包括使用中的malloc、new分配的堆空间和分配的栈空间,但不包括swap out量;

相比于 RES,VIRT还包括了进 程使用的库、代码、数据,受到 文章 http://bbs.chinaunix.net/thread-682816-1-1.html 的启发对 线程的申请释放进行了排查,通过 函数 pthread_setname_np 给每个线程取不同名字(15个字符) 参见 https://blog.csdn.net/lqy971966/article/details/104752947 ,重新编译并运行程序,通过 命令ps -T -p 进程号 查看某个进程的线程 ,可以发现有几个名字的线程数量在不断增加,线程没有回收释放,而这正是导致VIRT不断增加的原因,进一步分析代码问题还是出在数据模拟模块相关代码中。

本文链接地址:https://const.net.cn/672.html

标签: none

添加新评论