Linux中使用free可以查看系统内存使用状态, 默认单位为k
blue_stone@blueice:~$ free
total used free shared buffers cached
Mem: 2075320 1879172 196148 0 533484 952588
-/+ buffers/cache: 393100 1682220
Swap: 2008084 0 2008084
Mem 行显示了从系统角度看来内存使用的情况, total是系统可用的内存大小, 数量上等于系统物理内存减去内核保留的内存. buffers和cached是系统用做缓冲的内存. buffers与某个块设备关联, 包含了文件系统元数据, 并且跟踪了块的变化. cache只包含了文件本身.
-/+ buffers/cache行则从用户角度显示内存信息, 可用内存从数量上等于mem行used列值减去buffers和cached内存的大小. 因为buffers和cached是操作系统为加快系统运行而设置的, 当用户需要时, 可以只接为用户使用.
top和vmstat也显示了系统内存的信息, 和free的显示结果类似.
这些命令都是从/proc/meminfo中读取内存信息.
blue_stone@blueice:~$ cat /proc/meminfo
MemTotal: 2075320 kB
MemFree: 25016 kB
Buffers: 763564 kB
Cached: 879860 kB
SwapCached: 0 kB
Active: 1056968 kB
Inactive: 843136 kB
HighTotal: 917440 kB
HighFree: 13892 kB
LowTotal: 1157880 kB
LowFree: 11124 kB
SwapTotal: 2008084 kB
SwapFree: 2008084 kB
Dirty: 4708 kB
Writeback: 0 kB
Mapped: 707152 kB
Slab: 102728 kB
CommitLimit: 3045744 kB
Committed_AS: 691808 kB
PageTables: 2936 kB
VmallocTotal: 114680 kB
VmallocUsed: 14800 kB
VmallocChunk: 98800 kB
关于/proc/meminfo中各行的含意, 在内核源代码的Documentation/filesystems/proc.txt文件中有叙述,系统的真实内存大小可以用dmesg |grep [mM][eE][mM]看到。
blue_stone@blueice:~$ dmesg |grep [mM][eE][mM]
895MB HIGHMEM available.
1152MB LOWMEM available.
HighMem zone: 229360 pages, LIFO batch:31
Memory: 2073292k/2097088k available (1493k kernel code, 21648k reserved,
546k data, 196k init, 917440k highmem)
Freeing initrd memory: 1079k freed
MEM window: f8000000-f80fffff
highmem bounce pool size: 64 pages
Freeing unused kernel memory: 196k freed
ehci_hcd 0000:00:10.4: irq 177, io mem 0xf8121000
/dev/vmnet: hub 0 does not exist, allocating memory.
[fglrx] Maximum main memory to use for locked dma buffers: 1898 MBytes.
/dev/vmnet: hub 3 does not exist, allocating memory.
/dev/vmnet: hub 1 does not exist, allocating memory.
/dev/vmnet: hub 2 does not exist, allocating memory.
进程使用的内存可以用top, ps来查看top中有3个列 VIRT RES SHR, 标示了进程使用的内存情况, VIRT标识这个进程可以使用的内存总大小, 包括这个进程真实使用的内存, 映射过的文件, 和别的进程共享的内存等. RES标识这个这个进程真实占用内存的大小. SHR标识可以和别的进程共享的内存和库大小.
/proc/pid/status显示一个进程的详细状态, 下面是一个示例:
blue_stone@blueice:~$ cat /proc/5346/status
Name: bash
State: S (sleeping)
SleepAVG: 98%
Tgid: 5346
Pid: 5346
PPid: 5343
TracerPid: 0
Uid: 1000 1000 1000 1000
Gid: 104 104 104 104
FDSize: 256
Groups: 6 24 29 44 104 113 1000 1001
VmPeak: 6528 kB
VmSize: 6528 kB
VmLck: 0 kB
VmHWM: 1976 kB
VmRSS: 1976 kB
VmData: 752 kB
VmStk: 84 kB
VmExe: 644 kB
VmLib: 1788 kB
VmPTE: 16 kB
Threads: 1
SigQ: 0/4294967295
SigPnd: 0000000000000000
ShdPnd: 0000000000000000
SigBlk: 0000000000000000
SigIgn: 0000000000384004
SigCgt: 000000004b813efb
CapInh: 0000000000000000
CapPrm: 0000000000000000
CapEff: 0000000000000000
VmSize即为该进程内存总大小, 和top输出中的VIRT一致。
进程实际内存占用: 私有驻留内存数(Private RSS)介绍
先介绍几个基本概念:
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
下面我以本站使用的Fedora Core 5为例, 查看进程号1293(vmware-guestd, 本站使用的是一台基于vmware的客户虚拟机, 微睦独立主机)使用的Private RSS数.
CODE:
# cat /proc/1293/smaps
00111000-00112000 rwxp 00111000 00:00 0
Size: 4 kB
Rss: 4 kB
Shared_Clean: 0 kB
Shared_Dirty: 0 kB
Private_Clean: 0 kB
Private_Dirty: 4 kB
0050e000-0050f000 rwxp 0050e000 00:00 0
Size: 4 kB
Rss: 0 kB
Shared_Clean: 0 kB
Shared_Dirty: 0 kB
Private_Clean: 0 kB
Private_Dirty: 0 kB
0051a000-0051b000 r-xp 0051a000 00:00 0 [vdso]
Size: 4 kB
Rss: 4 kB
Shared_Clean: 4 kB
Shared_Dirty: 0 kB
Private_Clean: 0 kB
Private_Dirty: 0 kB
0051b000-00534000 r-xp 00000000 fd:00 194898 /lib/ld-2.4.so
Size: 100 kB
Rss: 0 kB
Shared_Clean: 0 kB
Shared_Dirty: 0 kB
Private_Clean: 0 kB
Private_Dirty: 0 kB
00534000-00535000 r-xp 00018000 fd:00 194898 /lib/ld-2.4.so
Size: 4 kB
Rss: 0 kB
Shared_Clean: 0 kB
Shared_Dirty: 0 kB
Private_Clean: 0 kB
Private_Dirty: 0 kB
00535000-00536000 rwxp 00019000 fd:00 194898 /lib/ld-2.4.so
Size: 4 kB
Rss: 0 kB
Shared_Clean: 0 kB
Shared_Dirty: 0 kB
Private_Clean: 0 kB
Private_Dirty: 0 kB
00538000-00665000 r-xp 00000000 fd:00 194905 /lib/libc-2.4.so
Size: 1204 kB
Rss: 212 kB
Shared_Clean: 204 kB
Shared_Dirty: 0 kB
Private_Clean: 8 kB
Private_Dirty: 0 kB
00665000-00667000 r-xp 0012d000 fd:00 194905 /lib/libc-2.4.so
Size: 8 kB
Rss: 8 kB
Shared_Clean: 4 kB
Shared_Dirty: 0 kB
Private_Clean: 0 kB
Private_Dirty: 4 kB
00667000-00668000 rwxp 0012f000 fd:00 194905 /lib/libc-2.4.so
Size: 4 kB
Rss: 4 kB
Shared_Clean: 0 kB
Shared_Dirty: 0 kB
Private_Clean: 0 kB
Private_Dirty: 4 kB
00668000-0066b000 rwxp 00668000 00:00 0
Size: 12 kB
Rss: 8 kB
Shared_Clean: 0 kB
Shared_Dirty: 0 kB
Private_Clean: 0 kB
Private_Dirty: 8 kB
08047000-08062000 r-xp 00000000 fd:00 292327 /usr/sbin/vmware-guestd
Size: 108 kB
Rss: 64 kB
Shared_Clean: 0 kB
Shared_Dirty: 0 kB
Private_Clean: 64 kB
Private_Dirty: 0 kB
08062000-08063000 rwxp 0001a000 fd:00 292327 /usr/sbin/vmware-guestd
Size: 4 kB
Rss: 4 kB
Shared_Clean: 0 kB
Shared_Dirty: 0 kB
Private_Clean: 0 kB
Private_Dirty: 4 kB
08063000-08068000 rwxp 08063000 00:00 0
Size: 20 kB
Rss: 12 kB
Shared_Clean: 0 kB
Shared_Dirty: 0 kB
Private_Clean: 0 kB
Private_Dirty: 12 kB
08385000-08886000 rwxp 08385000 00:00 0 [heap]
Size: 5124 kB
Rss: 5080 kB
Shared_Clean: 0 kB
Shared_Dirty: 0 kB
Private_Clean: 0 kB
Private_Dirty: 5080 kB
bfeb2000-bfec7000 rwxp bfeb2000 00:00 0 [stack]
Size: 84 kB
Rss: 12 kB
Shared_Clean: 0 kB
Shared_Dirty: 0 kB
Private_Clean: 0 kB
Private_Dirty: 12 kB
上面我们看到从smaps看不太方便, 推荐使用Ben Maurer写的perl脚本: (本地下载)
下面是由seme.pl脚本解析的smaps数据:
首先安装Linux::Smaps模块:
perl -MCPAN -e 'install Linux::Smaps'
然后用seme.pl解析1293进程的Smaps数据:
CODE:
# ./smem.pl 1293
VMSIZE: 7200 kb
RSS: 1052 kb total
192 kb shared
100 kb private clean
760 kb private dirty
PRIVATE MAPPINGS
vmsize rss clean rss dirty file
5636 kb 8 kb 724 kb [heap]
84 kb 0 kb 12 kb [stack]
4 kb 0 kb 4 kb
8 kb 0 kb 4 kb /lib/libc-2.4.so
4 kb 0 kb 4 kb /lib/libc-2.4.so
12 kb 4 kb 4 kb
4 kb 0 kb 4 kb /usr/sbin/vmware-guestd
20 kb 8 kb 4 kb
1204 kb 16 kb 0 kb /lib/libc-2.4.so
108 kb 64 kb 0 kb /usr/sbin/vmware-guestd
SHARED MAPPINGS
vmsize rss clean rss dirty file
1204 kb 188 kb 0 kb /lib/libc-2.4.so
4 kb 4 kb 0 kb [vdso]
从上面看到rss大小被分成了两个部分: private(私有)和shared(共享).
private rss就是我们最关心的进程实际占用的内存数.
============================================================
cat /proc/14593/smaps | grep Private_Dirty | awk '{sum+=$2};END{print sum}'
cat /proc/14593/smaps | grep Private_Clean | awk '{sum+=$2};END{print sum}'
============================================================
* VmSize:
虚拟内存大小。
整个进程使用虚拟内存大小,是VmLib, VmExe, VmData, 和 VmStk的总和。
* VmLck:
虚拟内存锁。
进程当前使用的并且加锁的虚拟内存总数
* VmRSS:
虚拟内存驻留集合大小。
这是驻留在物理内存的一部分。它没有交换到硬盘。它包括代码,数据和栈。
* VmData:
虚拟内存数据。
堆使用的虚拟内存。
* VmStk:
虚拟内存栈
栈使用的虚拟内存
* VmExe:
可执行的虚拟内存
可执行的和静态链接库所使用的虚拟内存
* VmLib:
虚拟内存库
动态链接库所使用的虚拟内存