Linux进程虚拟内存和物理内存 收藏 先介绍几个基本概念:
SIZE: 进程使用的地址空间, 如果进程映射了100M的内存, 进程的地址空间将报告为100M内存. 事实上, 这个大小不是一个程序实际使用的内存数.
RSS: "Resident Set Size", 实际驻留"在内存中"的内存数. 不包括已经交换出去的代码. 举一个例子: 如果你有一个程序使用了100K内存, 操作系统交换出40K内存, 那么RSS为60K. RSS还包括了与其它进程共享的内存区域. 这些区域通常用于libc库等.
SHARE: RSS中与其它进程共享的内存部分大小.
VMSIZE: 一个进程占用的总的地址空间大小. 它包括了没有映射到内存中的页面.
Private RSS: 映射到内存中的页面, 这些页面仅由进程单独使用. 这也是我们最关心地方: 进程实际占用的内存数.
如何来查看Private RSS呢? /proc接口中每一个进程目录下的smaps提供了private rss信息. smaps是在2.6.16内核版本引进来的.
私有驻留内存数(Private RSS):查看/proc/$pid/smaps
下面我以本站使用的Linux AS5为例, 查看进程号1293(vmware-guestd, 本站使用的是一台基于vmware的客户虚拟机,)使用的Private RSS数.
CODE: # cat /proc/1293/smaps 00111000-00112000 rwxp 00111000 00:00 0 Size: 4 kBRss: 4 kBShared_Clean: 0 kBShared_Dirty: 0 kBPrivate_Clean: 0 kBPrivate_Dirty: 4 kB0050e000-0050f000 rwxp 0050e000 00:00 0 Size: 4 kBRss: 0 kBShared_Clean: 0 kBShared_Dirty: 0 kBPrivate_Clean: 0 kBPrivate_Dirty: 0 kB0051a000-0051b000 r-xp 0051a000 00:00 0 [vdso]Size: 4 kBRss: 4 kBShared_Clean: 4 kBShared_Dirty: 0 kBPrivate_Clean: 0 kBPrivate_Dirty: 0 kB0051b000-00534000 r-xp 00000000 fd:00 194898 /lib/ld-2.4.soSize: 100 kBRss: 0 kBShared_Clean: 0 kBShared_Dirty: 0 kBPrivate_Clean: 0 kBPrivate_Dirty: 0 kB00534000-00535000 r-xp 00018000 fd:00 194898 /lib/ld-2.4.soSize: 4 kBRss: 0 kBShared_Clean: 0 kBShared_Dirty: 0 kBPrivate_Clean: 0 kBPrivate_Dirty: 0 kB00535000-00536000 rwxp 00019000 fd:00 194898 /lib/ld-2.4.soSize: 4 kBRss: 0 kBShared_Clean: 0 kBShared_Dirty: 0 kBPrivate_Clean: 0 kBPrivate_Dirty: 0 kB00538000-00665000 r-xp 00000000 fd:00 194905 /lib/libc-2.4.soSize: 1204 kBRss: 212 kBShared_Clean: 204 kBShared_Dirty: 0 kBPrivate_Clean: 8 kBPrivate_Dirty: 0 kB00665000-00667000 r-xp 0012d000 fd:00 194905 /lib/libc-2.4.soSize: 8 kBRss: 8 kBShared_Clean: 4 kBShared_Dirty: 0 kBPrivate_Clean: 0 kBPrivate_Dirty: 4 kB00667000-00668000 rwxp 0012f000 fd:00 194905 /lib/libc-2.4.soSize: 4 kBRss: 4 kBShared_Clean: 0 kBShared_Dirty: 0 kBPrivate_Clean: 0 kBPrivate_Dirty: 4 kB00668000-0066b000 rwxp 00668000 00:00 0 Size: 12 kBRss: 8 kBShared_Clean: 0 kBShared_Dirty: 0 kBPrivate_Clean: 0 kBPrivate_Dirty: 8 kB08047000-08062000 r-xp 00000000 fd:00 292327 /usr/sbin/vmware-guestdSize: 108 kBRss: 64 kBShared_Clean: 0 kBShared_Dirty: 0 kBPrivate_Clean: 64 kBPrivate_Dirty: 0 kB08062000-08063000 rwxp 0001a000 fd:00 292327 /usr/sbin/vmware-guestdSize: 4 kBRss: 4 kBShared_Clean: 0 kBShared_Dirty: 0 kBPrivate_Clean: 0 kBPrivate_Dirty: 4 kB08063000-08068000 rwxp 08063000 00:00 0 Size: 20 kBRss: 12 kBShared_Clean: 0 kBShared_Dirty: 0 kBPrivate_Clean: 0 kBPrivate_Dirty: 12 kB08385000-08886000 rwxp 08385000 00:00 0 [heap]Size: 5124 kBRss: 5080 kBShared_Clean: 0 kBShared_Dirty: 0 kBPrivate_Clean: 0 kBPrivate_Dirty: 5080 kBbfeb2000-bfec7000 rwxp bfeb2000 00:00 0 [stack]Size: 84 kBRss: 12 kBShared_Clean: 0 kBShared_Dirty: 0 kBPrivate_Clean: 0 kBPrivate_Dirty: 12 kB上面我们看到从smaps看不太方便, 推荐使用Ben Maurer写的perl脚本:
#!/usr/bin/perl
# Copyright Ben Maurer # you can distribute this under the MIT/X11 License
use Linux::Smaps;
my $pid=shift @ARGV;unless ($pid) { print "./smem.pl <pid>/n"; exit 1;}my $map=Linux::Smaps->new($pid);my @VMAs = $map->vmas;
format STDOUT =VMSIZE: @######## kb$map->sizeRSS: @######## kb total$map->rss @######## kb shared$map->shared_clean + $map->shared_dirty @######## kb private clean$map->private_clean @######## kb private dirty$map->private_dirty.
write; printPrivateMappings ();printSharedMappings ();
sub sharedMappings () { return grep { ($_->shared_clean + $_->shared_dirty) > 0 } @VMAs;}
sub privateMappings () { return grep { ($_->private_clean + $_->private_dirty) > 0 } @VMAs;}
sub printPrivateMappings (){ $TYPE = "PRIVATE MAPPINGS"; $^ = 'SECTION_HEADER'; $~ = 'SECTION_ITEM'; $- = 0; $= = 100000000; foreach $vma (sort {-($a->private_dirty <=> $b->private_dirty)} privateMappings ()) { $size = $vma->size; $dirty = $vma->private_dirty; $clean = $vma->private_clean; $file = $vma->file_name; write; }}
sub printSharedMappings (){ $TYPE = "SHARED MAPPINGS"; $^ = 'SECTION_HEADER'; $~ = 'SECTION_ITEM'; $- = 0; $= = 100000000; foreach $vma (sort {-(($a->shared_clean + $a->shared_dirty) <=> ($b->shared_clean + $b->shared_dirty))} sharedMappings ()) { $size = $vma->size; $dirty = $vma->shared_dirty; $clean = $vma->shared_clean; $file = $vma->file_name; write; }}
format SECTION_HEADER =@<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<$TYPE@>>>>>>>>>> @>>>>>>>>>> @>>>>>>>>> @<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<"vmsize" "rss clean" "rss dirty" "file".
format SECTION_ITEM =@####### kb @####### kb @####### kb @<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<$size $clean $dirty $file.下面是由seme.pl脚本解析的smaps数据:
首先安装Linux::Smaps模块:perl -MCPAN -e 'install Linux::Smaps'//需要网络,如无法上网,则可下载压缩包解压到 /root
然后用seme.pl解析1293进程的Smaps数据:
CODE: # ./smem.pl 1293VMSIZE: 7200 kbRSS: 1052 kb total192 kb shared100 kb private clean760 kb private dirtyPRIVATE MAPPINGSvmsize rss clean rss dirty file5636 kb 8 kb 724 kb [heap]84 kb 0 kb 12 kb [stack]4 kb 0 kb 4 kb8 kb 0 kb 4 kb /lib/libc-2.4.so4 kb 0 kb 4 kb /lib/libc-2.4.so12 kb 4 kb 4 kb4 kb 0 kb 4 kb /usr/sbin/vmware-guestd20 kb 8 kb 4 kb1204 kb 16 kb 0 kb /lib/libc-2.4.so108 kb 64 kb 0 kb /usr/sbin/vmware-guestd SHARED MAPPINGSvmsize rss clean rss dirty file1204 kb 188 kb 0 kb /lib/libc-2.4.so4 kb 4 kb 0 kb [vdso]
从上面看到rss大小被分成了两个部分: private(私有)和shared(共享).private rss就是我们最关心的进程实际占用的内存数.
本文来自博客,转载请标明出处:http://blog.csdn.net/youngtao/archive/2009/02/15/3891374.aspx