在 2.6.31-302 x86-64 内核上运行 Ubuntu。总体问题是,我的“缓存”类别中的内存不断增加,即使我们的应用程序需要它,也不会被释放或使用。
以下是我使用“免费”命令后得到的结果。乍一看,这些都没什么特别的。
# free
total used free shared buffers cached
Mem: 7358492 5750320 1608172 0 7848 1443820
-/+ buffers/cache: 4298652 3059840
Swap: 0 0 0
有人会说的第一句话是“别担心,Linux 会自动管理这些内存。”是的,我知道内存管理器应该如何工作;问题是它没有做正确的事情。这里“缓存”的 1.4 GB 似乎被保留了,无法使用。
我对 Linux 的了解告诉我 3 GB 是“空闲”的;但系统的行为却并非如此。当 1.6 GB 的实际空闲内存在高峰使用期间用完时,一旦需要更多内存(并且第一列中的“空闲”接近 0),就会调用 OOM 终止程序,终止进程,并开始出现问题虽然-/+ buffers/cache 行中的‘free’仍然有大约 1.4 GB 的‘free’空间。
我已经调整了关键进程的 oom_adj 值,这样系统就不会崩溃,但即便如此,重要的进程也会被终止,我们永远不想达到那个地步。尤其是当理论上 1.4GB 仍然是“空闲”的,如果它只会驱逐磁盘缓存的话。
有人知道这是怎么回事吗?互联网上充斥着有关 Linux 'free' 命令和“为什么我没有可用内存”的愚蠢问题,因此我找不到有关此问题的任何信息。
我首先想到的是交换已关闭。我们的系统管理员对此非常坚持;如果他们有备份,我愿意接受解释。这会引起问题吗?
运行后如下图所示echo 3 > /proc/sys/vm/drop_caches
:
# free
total used free shared buffers cached
Mem: 7358492 5731688 1626804 0 524 1406000
-/+ buffers/cache: 4325164 3033328
Swap: 0 0 0
如您所见,实际上释放了一些极少量的缓存,但大约 1.4 GB 似乎“卡住了”。另一个问题是,这个值似乎会随着时间的推移而上升。在另一台服务器上,2.0 GB 被卡住了。
我真的很想找回这个记忆……任何帮助都将不胜感激。
cat /proc/meminfo
如果它有价值的话,那就这样吧:
# cat /proc/meminfo
MemTotal: 7358492 kB
MemFree: 1472180 kB
Buffers: 5328 kB
Cached: 1435456 kB
SwapCached: 0 kB
Active: 5524644 kB
Inactive: 41380 kB
Active(anon): 5492108 kB
Inactive(anon): 0 kB
Active(file): 32536 kB
Inactive(file): 41380 kB
Unevictable: 0 kB
Mlocked: 0 kB
SwapTotal: 0 kB
SwapFree: 0 kB
Dirty: 320 kB
Writeback: 0 kB
AnonPages: 4125252 kB
Mapped: 42536 kB
Slab: 29432 kB
SReclaimable: 13872 kB
SUnreclaim: 15560 kB
PageTables: 0 kB
NFS_Unstable: 0 kB
Bounce: 0 kB
WritebackTmp: 0 kB
CommitLimit: 3679244 kB
Committed_AS: 7223012 kB
VmallocTotal: 34359738367 kB
VmallocUsed: 7696 kB
VmallocChunk: 34359729675 kB
DirectMap4k: 7340032 kB
DirectMap2M: 0 kB
答案1
我找到了我自己问题的答案——感谢 womble 的帮助(如果您愿意,请提交答案)。
lsof -s
显示正在使用的文件句柄,结果发现有几 GB 的 mmap 日志文件占用了缓存。
实施 logrotate 应该可以完全解决问题并允许我利用更多内存。
我还将重新启用交换,以便将来我们不会遇到 OOM 杀手的问题。谢谢。
答案2
显然,postgres'shared_buffers
可以出现在中cached
,但实际上并不容易被丢弃...参见尽管有可用内存(缓存),但 OOM
答案3
我遇到了类似的问题,文件系统选择不正确。切换到系统xfs
解决tmpfs
了这个问题。tmpfs
系统将所有 RAM 用作页面缓存,导致 OOM 终止程序最终终止了我的进程。