如何确定Linux下一个进程所占用的内存大小?这看起来超简单,top或者ps一下就能看出来。今天研究了一下发现并没有这么简单,相反还比较复杂。
以TOP为例,它有若干指示内存占用的列,从man top里摘抄如下:
n: %MEM – Memory usage (RES)
A task’s currently used share of available physical memory.
o: VIRT – Virtual Image (kb)
The total amount of virtual memory used by the task. It includes all code, data and shared libraries plus pages that have been swapped out.
VIRT = SWAP + RES.
p: SWAP – Swapped size (kb)
The swapped out portion of a task’s total virtual memory image.
q: RES – Resident size (kb)
The non-swapped physical memory a task has used.
r: CODE – Code size (kb)
The amount of virtual memory devoted to executable code, also known as the ‘text resident set’ size or TRS.
s: DATA – Data+Stack size (kb)
The amount of virtual memory devoted to other than executable code, also known as the ‘data resident set’ size or DRS.
t: SHR – Shared Mem size (kb)
The amount of shared memory used by a task. It simply reflects memory that could be potentially shared with other processes.
首先是MEM大有深意。”share of available physical memory”,意为可用物理内存的共享。这说明代表的是在真正的物理内存使用大小,不包括换页到swap上的部分。而且这个”share”说明这个大小可能被多个进程共享,最典型的是父子进程。MEM就是RES/物理内存大小 * 100%
其次VIRT是”the total amount of virtual memory used by the task”,说明这是这个进程的使用整个进程空间大小。
再次SWAP是VIRT与RES的差值。意为被换页出去的内存大小。看起来这部分内存被放到SWAP分区上了,但简单计算一下就可以看出不是这么回事儿,每个进程的SWAP大小加起来要远远超过所使用的SWAP分区的大小。
再次CODE和DATA分别代表代码段和数据与堆栈段,CODE+DATA与VIRT接近,但从观察的结果来看,不一定接近。
以进程pcmanx为例,CODE(248kb) + DATA(78mb) 远小于RES(10mb) + SWAP(243mb)。
这说明,进程空间往往远大于CODE+DATA。因为在执行过程中会free掉部分malloc出来的内存,进程空间没有减小,但DATA段大小减小。这样分析是否正确?
最后SHR看起来就没什么意义,因为”could be potentially shared with other processes”可能也就代表代码段和动态链接的库的大小?这只是我的猜测。
因此可以总结为,从RES看物理内存中的占用量,但这部分占用量是可能被”share”的;从VIRT看进程的进程空间大小,从DATA看进程现在所持有的数据大小。