我们习惯性的会看下那个进程在泄漏内存,我这里使用一个test_malloc的测试进程,该进程每2秒钟会分配一个10000字节的空间,并作简单赋值(注意:如果仅malloc而不使用,编译器会优化,实际测试时将看不到内存泄漏的测试效果):
这里的VSZ和RSS的单位是kb,程序运行前:
lark@ubuntu:~$ ps -aux | grep "malloc"
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
lark 2336 0.0 0.0 2496 576 pts/0 S+ 00:16 0:00 ./malloc
虚拟内存 2496*1k /1024/1024 = 2.5M左右 物理内存: 576*1k/1024/1024 = 0.5M左右
程序运行一段时间后:
lark@ubuntu:~$ ps -aux | grep "malloc"
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
lark 2336 0.0 0.9 20580 19056 pts/0 S+ 00:16 0:01 ./malloc
虚拟内存: 20580 *1k /1024/1024 = 20M左右 物理内存: 19056 *1k/1024/1024 = 19M左右
这样对比可以看到该malloc进程有明显的内存泄露。
1,查看/proc/meminfo
主要监控系统还有MemFree,对比前后两次的Memfree。
lark@ubuntu:~$ cat /proc/meminfo
MemTotal: 1974040 kB
MemFree: 149104 kB
MemAvailable: 762944 kB
Buffers: 45088 kB
Cached: 681120 kB
SwapCached: 0 kB
Active: 315612 kB
Inactive: 969976 kB
Active(anon): 1632 kB
Inactive(anon): 562180 kB
Active(file): 313980 kB
Inactive(file): 407796 kB
SwapTotal: 2097148 kB
SwapFree: 2097148 kB
Dirty: 196 kB
AnonPages: 559404 kB
Mapped: 256972 kB
Shmem: 4420 kB
KReclaimable: 66448 kB
Slab: 162704 kB
SReclaimable: 66448 kB
SUnreclaim: 96256 kB
KernelStack: 11168 kB
PageTables: 13724 kB
VmallocTotal: 34359738367 kB
VmallocUsed: 61388 kB
进程运行一段时间后的meminfo信息
lark@ubuntu:~$ cat /proc/meminfo
MemTotal: 1974040 kB
MemFree: 129160 kB
MemAvailable: 753136 kB
Buffers: 45184 kB
Cached: 681128 kB
SwapCached: 0 kB
Active: 316100 kB
Inactive: 983808 kB
Active(anon): 1632 kB
Inactive(anon): 576392 kB
Active(file): 314468 kB
Inactive(file): 407416 kB
SwapTotal: 2097148 kB
SwapFree: 2097148 kB
Dirty: 0 kB
AnonPages: 573672 kB
Mapped: 256984 kB
Shmem: 4428 kB
KReclaimable: 66500 kB
Slab: 162764 kB
SReclaimable: 66500 kB
SUnreclaim: 96264 kB
KernelStack: 11152 kB
PageTables: 13708 kB
VmallocTotal: 34359738367 kB
VmallocUsed: 61388 kB
MemFree前后变化 MemFree从 149104KB降为 129160 kB,少了20M左右,看SReclaimable前后没有变化。
2,查看进程状态属性stat/statm/status里面的VSZ和RSS
查看物理内存占用,通过/proc/pid/stat或/proc/pid/statm(这里不能设置字体颜色,以粗体表示)
lark@ubuntu:~$ cat /proc/2336/statm
1152 804 271 1 0 605 0
所有数值均以内存页(page)为单位(通常1页=4KB),我们看到的1152 表示VSZ,804表示物理内存RSS ,271是共享内存页数,1表示文本段(代码)占用页数。0是库文件占用页数,605 是数据段+栈占用页数,0是 脏页数量。
lark@ubuntu:~$ cat /proc/2336/statm
5442 5094 271 1 0 4895 0
5442*4k/1024/1024 = 20M左右
lark@ubuntu:~$ cat /proc/2336/status
Name: malloc
Umask: 0002
State: S (sleeping)
Tgid: 2336
Ngid: 0
Pid: 2336
PPid: 2177
TracerPid: 0
Uid: 1000 1000 1000 1000
Gid: 1000 1000 1000 1000
FDSize: 256
Groups: 4 24 27 30 46 120 133 134 1000
NStgid: 2336
NSpid: 2336
NSpgid: 2336
NSsid: 2177
VmPeak: 4740 kB
VmSize: 4740 kB
VmLck: 0 kB
VmPin: 0 kB
VmHWM: 3216 kB
VmRSS: 3216 kB
RssAnon: 2132 kB
RssFile: 1084 kB
RssShmem: 0 kB
VmData: 2420 kB
VmStk: 132 kB
VmExe: 4 kB
VmLib: 1652 kB
VmPTE: 44 kB
VmSwap: 0 kB
HugetlbPages: 0 kB
CoreDumping: 0
THP_enabled: 1
Threads: 1
SigQ: 0/7336
SigPnd: 0000000000000000
ShdPnd: 0000000000000000
SigBlk: 0000000000000000
SigIgn: 0000000000000000
SigCgt: 0000000000000000
CapInh: 0000000000000000
CapPrm: 0000000000000000
CapEff: 0000000000000000
CapBnd: 000001ffffffffff
CapAmb: 0000000000000000
NoNewPrivs: 0
Seccomp: 0
Seccomp_filters: 0
Speculation_Store_Bypass: thread vulnerable
SpeculationIndirectBranch: conditional enabled
Cpus_allowed: ffffffff,ffffffff,ffffffff,ffffffff
Cpus_allowed_list: 0-127
Mems_allowed: 00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000001
Mems_allowed_list: 0
voluntary_ctxt_switches: 2230
nonvoluntary_ctxt_switches: 0
虚拟内存相关参数:
VmSize: 4740 kB:当前虚拟内存占用总量(含共享库)
VmPeak: 4740 kB:历史峰值虚拟内存(本例中与当前值相同)
物理内存相关参数:
VmRSS: 3216 kB:实际驻留物理内存量(含共享内存)
RssAnon: 2132 kB:匿名页占用(如堆/栈),RssFile: 1084 kB为文件映射内存1
VmHWM: 3216 kB:物理内存使用峰值(与当前VmRSS一致)
内存泄漏嫌疑:若VmSize(
当前虚拟内存占用总量)
持续增长而VmRSS
不变,可能存在虚拟内存泄漏。
3,stat参数解析说明:
lark@ubuntu:~$ cat /proc/2336/stat
2336 (malloc) S 2177 2336 2177 34816 2336 1077936128 623 0 0 0 0 14 0 0 20 0 1 0 74181 4718592 804 18446744073709551615 94518316240896 94518316241573 140725828707728 0 0 0 0 0 0 1 0 0 17 6 0 0 0 0 0 94518316252584 94518316253200 94519079710720 140725828715633 140725828715642 140725828715642 1407258287185750
(1)基础进程信息描述
pid (2336)
进程ID,与文件名中的2336一致。
comm (malloc)
进程名称,括号包裹的可执行文件名。
state (S)
进程状态:
S:可中断睡眠(等待事件)
其他可能值:R(运行)、D(不可中断睡眠)、Z(僵尸)等。
ppid (2177)
父进程ID。
pgrp (2336)
进程组ID,通常与进程ID相同。
(2)、资源统计信息
session (2177)
会话ID,通常与父进程ID相同。
tty_nr (34816)
控制终端设备号,34816对应pts/0类终端。
utime (0)
用户态CPU时间(单位:时钟滴答,jiffies)。
stime (14)
内核态CPU时间(jiffies)
cutime/cstime (0/0)
所有已终止子进程的累计用户态/内核态CPU时间。
(3)、内存相关字段
priority (20)
进程静态优先级(数值越小优先级越高)。
nice (0)
nice值,影响动态优先级调整。
num_threads (1)
进程包含的线程数。
start_time (74181)
进程启动时间(单位:时钟滴答,从系统启动算起)。
vsize (4718592)
虚拟内存大小(字节),此处约4.5MB
rss (804)
驻留物理内存页数(每页通常4KB,此处约3.1MB)。
(4)、其他关键字段
exit_signal (17)
进程终止时发送给父进程的信号。
processor (6)
最后一次运行的CPU编号。
rt_priority (0)
实时进程优先级(0表示非实时进程)。
blkio_ticks (0)
块设备I/O等待时间(jiffies)。