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

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

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

然而,当它崩溃时,系统仍然处于内存不足的状态。我不确定这是否只是我遗漏的一个进程,还是一个实际的错误(这是在 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

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

那么最大的内存消耗者是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

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

答案1

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

Linux 上的共享内存有三种变体:

1.) POSIX 共享内存(由 glibc 实现的内存)可通过tmpfs伪文件系统上的文件访问,并且通常由系统挂载在/dev/shm/run/run/shm等位置/run/lock。确定的最佳方法是在 shell 中输入mount | grep -E '^tmpfs'(更便携)或(最适合 Linux)。grep -E '^tmpfs' /proc/mounts

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

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

3.) 匿名映射共享内存,在这种情况下,内存不受任何文件支持,而是内存最初在进程及其所有子进程之间共享。据我所知,当mmap()编辑它的进程运行时,这种匿名映射共享内存就会被释放exit()。因此,如果您的程序终止并且其所有子进程也终止,那么它们不应该进一步占用任何内存。

相关内容