我的虚拟机存在内存问题。我想在其中运行的任务之一是因内存不足错误而崩溃。
然而,当它崩溃时,系统仍然处于内存不足的状态。我不确定这是否只是我遗漏的一个进程,还是一个实际的错误(这是在 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()
。因此,如果您的程序终止并且其所有子进程也终止,那么它们不应该进一步占用任何内存。