查找占用大量内存且在`ps` 或类似内容中不可见的内容

Fak*_*ame 2 memory out-of-memory

我有一个存在内存问题的虚拟机。我想在其中运行的任务之一是因内存不足错误而崩溃。

然而,当它崩溃时,系统仍然保持内存不足。我不确定这是否只是我遗漏的一个进程,还是一个实际的错误(这是在 hyper-v 中,具有允许 linux 主机内存膨胀的新内核扩展,因此它很可能是一个真正的内核错误)。

durr@sqlbox:~$ free -h
             total       used       free     shared    buffers     cached
Mem:          3.1G       2.6G       541M        88K       7.4M        39M
-/+ buffers/cache:       2.5G       588M
Swap:         1.0G       6.2M       1.0G
Run Code Online (Sandbox Code Playgroud)

Free 告诉我,它不只是缓存,实际上有一些东西似乎正在占用 2.6G 内存。

但是,查看按虚拟大小排序的 PS 输出并不具有启发性:

durr@sqlbox:~$ ps -e ax -o pid,vsz,comm | sort --numeric-sort --key=2
[ ... snip ... ]
  PID    VSZ COMMAND
   96      0 rcuob/23
   97      0 rcuob/24
   98      0 rcuob/25
   99      0 rcuob/26
 1124   4368 acpid
59863  10016 ps
 1031  15668 upstart-file-br
 1047  15820 getty
 1050  15820 getty
 1055  15820 getty
 1056  15820 getty
 1058  15820 getty
 1167  15820 getty
 1023  15920 upstart-socket-
 1076  19140 atd
 1099  19188 irqbalance
  428  19476 upstart-udev-br
59864  21860 sort
59267  22644 bash
59234  22664 bash
59280  22808 bash
 1075  23656 cron
59261  26928 screen
59279  27380 htop
59262  28472 screen
    1  33776 init
  749  39240 dbus-daemon
  816  43452 systemd-logind
  432  51348 systemd-udevd
 1090  61364 sshd
  871 255844 rsyslogd
59184 269028 sshd
59233 269028 sshd
Run Code Online (Sandbox Code Playgroud)

所以最大的内存消耗者是sshd,它使用..... 269K?我所有的记忆都去哪儿了?

/proc/meminfo节目:

durr@sqlbox:~$ cat /proc/meminfo
MemTotal:        3266904 kB
MemFree:          554228 kB
Buffers:            7596 kB
Cached:            41104 kB
SwapCached:         3032 kB
Active:            32552 kB
Inactive:          34292 kB
Active(anon):      13224 kB
Inactive(anon):     5008 kB
Active(file):      19328 kB
Inactive(file):    29284 kB
Unevictable:           0 kB
Mlocked:               0 kB
SwapTotal:       1044476 kB
SwapFree:        1038084 kB
Dirty:                 0 kB
Writeback:             0 kB
AnonPages:         15656 kB
Mapped:             9196 kB
Shmem:                88 kB
Slab:              33488 kB
SReclaimable:      14532 kB
SUnreclaim:        18956 kB
KernelStack:        2352 kB
PageTables:         2748 kB
NFS_Unstable:          0 kB
Bounce:                0 kB
WritebackTmp:          0 kB
CommitLimit:     2677928 kB
Committed_AS:      56148 kB
VmallocTotal:   34359738367 kB
VmallocUsed:       34360 kB
VmallocChunk:   34359695660 kB
HardwareCorrupted:     0 kB
AnonHugePages:         0 kB
HugePages_Total:       0
HugePages_Free:        0
HugePages_Rsvd:        0
HugePages_Surp:        0
Hugepagesize:       2048 kB
DirectMap4k:       44456 kB
DirectMap2M:     3491840 kB
Run Code Online (Sandbox Code Playgroud)

显然,似乎有些东西Vmalloc占用了大量内存,但我不确定这是否相关。

Fra*_*nki 5

您的程序可能使用了共享内存并且没有清理它。

linux上共享内存的三种变体:

1.)POSIX共享存储器(一个由glibc的实现)是经由上的文件访问的tmpfs伪文件系统,通常被安装在系统上的地方,如/dev/shm/run/run/shm/run/lock。确定的最佳方法是在 shell 中输入mount | grep -E '^tmpfs'(更便携)或grep -E '^tmpfs' /proc/mounts(最适合 linux)。

请注意,进程可能会调用共享内存中unlink()mmap()'ed 文件,从而无法通过文件名访问该文件(例如,需要先前分配的文件句柄才能继续访问它)。然而,unlink()ed 文件通常在退出所有被 ed 的进程时被删除open()——也许如果你的程序完成了,还有另一个进程仍然持有它的句柄。

2.) SysV IPC 共享内存,无法通过tmpfs伪文件系统看到,而是通过/proc/sysvipc/shm, linux 系统调用(仅当您是黑客时)、其 libc 包装器或最近通过ipcs -m -p -[tclu]. 您需要在任何这些列表中找到匹配的进程 ID,然后进一步检查该进程。

3.) 匿名映射共享内存,在这种情况下,内存不受任何文件支持,而是最初在进程及其所有子进程之间共享内存。AFAIK 这样的匿名映射共享内存在处理mmap()exit()的进程时被释放。因此,如果您的程序终止并且它的所有子进程也终止了,它们不应该进一步占用任何内存。