Linux进程的内存使用解析
展开全部
进程XXX占用了多少内存?这是个经常被问到,也经常被答错的问题。linux进程的内存分配是个比较复杂的话题,而linux上的工具往往把这个问题过分简单化,因此引出不少误解和困惑。首先把ps,
top这类工具扔掉,然后看这么一个简单程序: [root@pczou
pczou]#
cat
./prog.c #i
nclude #i
nclude #i
nclude #i
nclude #define
ONEM
(1024*1024)
www.zhishiwu.com
int
func() { char
s[16*ONEM]; char*
p; p
=
malloc(32*ONEM); pause(); return
0; } int
main() { printf(pid:
%d/n,
getpid()); func(); return
0; } 其中func()这个函数分配了32MB的内存,以及16MB的堆栈。 运行一下这个prog程序,prog会停在pause()的位置,看看ps怎么说: USER
PID
%CPU
%MEM
VSZ
RSS
TTY
STAT
START
TIME
COMMAND root
4238
0.0
0.0
52396
352
pts/0
S
21:29
0:00
./prog VSZ指的是进程内存空间的大小,这里是52396KB; RSS指的是驻留物理内存中的内存大小,这里是352KB。 一般系统管理员知道VSZ并不代表进程真正用到的内存,因为有些空间会仅在页表中挂个名,也就是说只是虚拟存在着,只有真正用到的时候内核才会把虚拟页面和真正的物理页面映射起来。比如,prog.c中用malloc()分配的32MB内存,由于程序中并没有用到这些内存,没有物理内存被分配,也就不应算到进程的帐上。
www.zhishiwu.com
进程的内存使用情况比较复杂,这是因为: 进程所申请的内存不一定真正会被用到 真正用到了的内存也不一定是只有该进程自己在用
(比如动态共享库) 所以酒足饭饱结帐的时候,饭馆打出的帐单中往往漏洞百出,不是计入了没上的菜,就是一个菜算了两份钱。而ps给出的就是这样的糊涂帐单,不足为凭。 算清楚帐的唯一办法是把每个菜都仔细过一遍,看看有没有上,有没有重复。下面的帐单要清楚多了: Virtual
memory
:
52396
KB Effective
VM
:
52120
KB Mapped
:
352
KB Effective
mapped:
76.6
KB Sole
use
:
72
KB Per
file
memory
use ld-2.3.4.so
:
VM
94208
B,
M
90112
B,
S
8192
B prog
:
VM
8192
B,
M
8192
B,
S
8192
B libc-2.3.4.so
:
VM
1180
KB,
M
221184
B,
S
16384
B 可以看出,虽然虚拟地址空间是52396KB,实际映射(a.k.a.
分配)的空间是352KB,这和ps给出的结果一致。再看Effective
Mapped这个值,仅为76.6
KB。这个值的计算方法是: 有效的实际使用内存
=
该进程独占的内存
+
共享的内存A
/共享A的进程数目
+
共享的内存B
/共享B的进程数目
+
... 比如对于一个kde应用程序kontact,它用的Qt库的虚拟地址空间为
7M,而实际映射的空间有4.5M,也就是说真正给
Qt分配物理内存大小为4.5M。假设有10个KDE应用正在运行,那么记到kontact帐上的就不应该是4.5M,而是A-A之后的0.45M。这么算帐虽然并不十分准确,但Effective
Mapped已经足以说明进程所占用内存的实际大小了。
www.zhishiwu.com
OK,最后用这个方法给系统中所有进程都结下帐: 从上面的统计结果可以看出: 虽然firefox的占用虚拟空间是最大的,但其实际占用的内存却比X
Server要少。 firefox
的实际占用的内存和其RSS
(a.k.a.
mapped)差别不大,占RSS的99%;而kontact的实际占用内存却仅占RSS的63%,有27%的内存是共享的。由此可以粗略看出我用的窗口管理器是KDE而非Gnome,why?
因为Qt之类的共享库被很多KDE进程分担了。 sole值可以理解为private
mapped,也就是这个进程退出后可能被释放的内存
(对于非匿名的映射页面可能还会存留一段时间)。作者
railon
top这类工具扔掉,然后看这么一个简单程序: [root@pczou
pczou]#
cat
./prog.c #i
nclude #i
nclude #i
nclude #i
nclude #define
ONEM
(1024*1024)
www.zhishiwu.com
int
func() { char
s[16*ONEM]; char*
p; p
=
malloc(32*ONEM); pause(); return
0; } int
main() { printf(pid:
%d/n,
getpid()); func(); return
0; } 其中func()这个函数分配了32MB的内存,以及16MB的堆栈。 运行一下这个prog程序,prog会停在pause()的位置,看看ps怎么说: USER
PID
%CPU
%MEM
VSZ
RSS
TTY
STAT
START
TIME
COMMAND root
4238
0.0
0.0
52396
352
pts/0
S
21:29
0:00
./prog VSZ指的是进程内存空间的大小,这里是52396KB; RSS指的是驻留物理内存中的内存大小,这里是352KB。 一般系统管理员知道VSZ并不代表进程真正用到的内存,因为有些空间会仅在页表中挂个名,也就是说只是虚拟存在着,只有真正用到的时候内核才会把虚拟页面和真正的物理页面映射起来。比如,prog.c中用malloc()分配的32MB内存,由于程序中并没有用到这些内存,没有物理内存被分配,也就不应算到进程的帐上。
www.zhishiwu.com
进程的内存使用情况比较复杂,这是因为: 进程所申请的内存不一定真正会被用到 真正用到了的内存也不一定是只有该进程自己在用
(比如动态共享库) 所以酒足饭饱结帐的时候,饭馆打出的帐单中往往漏洞百出,不是计入了没上的菜,就是一个菜算了两份钱。而ps给出的就是这样的糊涂帐单,不足为凭。 算清楚帐的唯一办法是把每个菜都仔细过一遍,看看有没有上,有没有重复。下面的帐单要清楚多了: Virtual
memory
:
52396
KB Effective
VM
:
52120
KB Mapped
:
352
KB Effective
mapped:
76.6
KB Sole
use
:
72
KB Per
file
memory
use ld-2.3.4.so
:
VM
94208
B,
M
90112
B,
S
8192
B prog
:
VM
8192
B,
M
8192
B,
S
8192
B libc-2.3.4.so
:
VM
1180
KB,
M
221184
B,
S
16384
B 可以看出,虽然虚拟地址空间是52396KB,实际映射(a.k.a.
分配)的空间是352KB,这和ps给出的结果一致。再看Effective
Mapped这个值,仅为76.6
KB。这个值的计算方法是: 有效的实际使用内存
=
该进程独占的内存
+
共享的内存A
/共享A的进程数目
+
共享的内存B
/共享B的进程数目
+
... 比如对于一个kde应用程序kontact,它用的Qt库的虚拟地址空间为
7M,而实际映射的空间有4.5M,也就是说真正给
Qt分配物理内存大小为4.5M。假设有10个KDE应用正在运行,那么记到kontact帐上的就不应该是4.5M,而是A-A之后的0.45M。这么算帐虽然并不十分准确,但Effective
Mapped已经足以说明进程所占用内存的实际大小了。
www.zhishiwu.com
OK,最后用这个方法给系统中所有进程都结下帐: 从上面的统计结果可以看出: 虽然firefox的占用虚拟空间是最大的,但其实际占用的内存却比X
Server要少。 firefox
的实际占用的内存和其RSS
(a.k.a.
mapped)差别不大,占RSS的99%;而kontact的实际占用内存却仅占RSS的63%,有27%的内存是共享的。由此可以粗略看出我用的窗口管理器是KDE而非Gnome,why?
因为Qt之类的共享库被很多KDE进程分担了。 sole值可以理解为private
mapped,也就是这个进程退出后可能被释放的内存
(对于非匿名的映射页面可能还会存留一段时间)。作者
railon
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
推荐律师服务:
若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询