我的磁盘上没有交换分区,因为我更喜欢让 OOM 收割者快速杀死它想要的任何东西,而不是等待 10 分钟让我的交换分区填满 + 其他 5 分钟才能启动 OOM 收割者 + 崩溃。基本上,我的问题是:
eat_all_my_memory;top并查看 akworker正在“工作”;eat_all_my_memory他被杀了;上次用了12分钟。我尝试登录 TTY 似乎对整个周期时间没有影响。那么我有几个问题:
我在 Debian、Ubuntu 和现在的 Archlinux 上都遇到了问题,所以这似乎不是特定于发行版的。
编辑:日志文件的摘录
我在 15:28 左右启动了违规命令。似乎系统实际上需要很多时间才能弄清楚没有任何东西。
déc. 11 15:28:56 hostname dbus[475]: [system] Failed to activate service 'org.freedesktop.ModemManager1': timed out
déc. 11 …Run Code Online (Sandbox Code Playgroud) 我正在使用 Linux 5.15 和 Ubuntu 22.04。
我有一个使用大量内存的进程。它需要的内存比我机器上的 RAM 还要多。我第一次运行它时,它被 OOM Killer 杀死了。我的理解是:系统内存不足,OOM Killer 被触发,我的进程被杀死。这是有道理的。我也确信这就是发生的事情:我看了一下dmesg,一切都在那里。
所以我添加了一些交换空间。我不介意这个过程是否需要很长时间才能运行:我不会经常运行它。
我再次运行该过程。这次比第一次跑的时间更长。整个系统变得非常滞后,系统在进行大量交换时就会出现这种情况。它似乎起作用了……然后就死了。不仅进程死了,它的父进程 shell 进程也死了,它的父进程 Tmux 进程、Tmux 进程的父进程 shell 进程,甚至它的父 GNOME 终端进程也死了!但随后谋杀过程停止了:不再有父母死亡。
起初,我以为 OOM Killer 再次被触发——尽管仍有大量交换空间可用——并且它选择终止 GNOME 终端进程。但我查了dmesg一下,journalctl -k并没有什么新的东西。没有任何迹象表明 OOM Killer 已被触发。
那么,第一个问题:是否有任何情况可以触发 OOM Killer,而不将任何内容记录到内核环形缓冲区?
让我困惑的是,Linux 内核似乎已经开始交换,但不知何故它交换得不够……或者交换得不够快……或者其他什么。
所以我增加了vm.swappiness。这确实不应该影响系统稳定性:它只是一个用于性能优化的旋钮。即使vm.swappiness设置为0内核,当区域中的可用内存降至临界阈值以下时,内核仍应开始交换。
但似乎它已经开始交换,但交换得还不够……所以我增加了vm.swappiness鼓励100它交换更多一点。
然后我再次运行该过程。整个系统变得非常滞后,系统在进行大量交换时就会这样做......直到进程成功运行完成。
那么,第二个问题:为什么内核不使用可用的交换空间,即使空闲内存已降至临界阈值以下并且肯定有足够的可用交换空间?为什么改变会vm.swappiness带来改变?
更新:
进一步的测试表明该设置vm.swappiness不是一个可靠的解决方案。即使vm.swappinessset to ,我也遇到过一些失败100。它可能会提高该过程成功完成的机会,但我不确定。
在我有 512 MB RAM 和 348 MB 交换的 Debian VM 机器上,如果我在编辑器中打开一个 1 GB 的文件并且内存不足会发生什么?
会不会导致系统崩溃?或者如果没有,Linux 将如何处理?
安装Swapspace是否明智,以便在需要时自动和动态地创建足够的交换?
sudo apt-get install swapspace
Run Code Online (Sandbox Code Playgroud) 输出free显示我的应用程序只使用 2GB,完全没有使用交换。然而我的应用程序被杀死了(Skype、Firefox、Thunderbird)。我看着它,htop看起来他们分配了几兆字节并被杀死了。我不得不重新启动以“修复”问题。
我的问题是为什么,更重要的是,当这种情况再次发生时如何修复它(我的意思是除了重启)?(编辑3)
这很烦人,我丢失了很长的帖子(Firefox 被杀死而没有任何通知)和其他东西。在 Linux 上是否正常,在 80% 的可用内存上杀死应用程序 b/c OOM 并且根本没有尝试使用交换?
编辑:发行版是 Kubuntu 16.04。
EDIT2:日志(小片段,帖子长度限制的 b/c):
[ 2687.946164] Xorg invoked oom-killer: gfp_mask=0x24040c0, order=3, oom_score_adj=0
[ 2687.946167] Xorg cpuset=/ mems_allowed=0
[ 2687.946171] CPU: 3 PID: 2109 Comm: Xorg Tainted: P OE 4.4.0-59-generic #80-Ubuntu
[ 2687.946172] Hardware name: MSI MS-7850/B85-G41 PC Mate(MS-7850), BIOS V2.9 03/30/2015
[ 2687.946174] 0000000000000286 00000000828bbbc2 ffff880409ad38d8 ffffffff813f7583
[ 2687.946176] ffff880409ad3ab0 ffff880392c09c00 ffff880409ad3948 ffffffff8120ad5e
[ 2687.946177] 0000000000000015 0000000000000000 ffff8802e4f47180 ffff8800033c2a00 …Run Code Online (Sandbox Code Playgroud) kvm 版本:QEMU emulator version 1.1.2 (qemu-kvm-1.1.2+dfsg-6+deb7u3, Debian), Copyright (c) 2003-2008 Fabrice Bellard
libvirtd 版本:libvirtd (libvirt) 0.9.12.3
debian 版本:7.5
我在 16GB RAM 的机器上运行多个 VM,它们一起使用 ~9GB RAM。
linux oom 杀手时不时会过来杀死一个进程。我猜它会选择使用大部分内存的进程 - 在这种情况下是 6GB Windows VM:
[431215.778365] Out of memory: Kill process 25086 (kvm) score 192 or sacrifice child
恕我直言,机器不应该处于 OOM 情况,因为有大约 6.6GB 的缓存可用内存。您可以在此处查看内存分布和由此产生的 oom kill:

我现在已将oom_adjkvm 的 pid设置为-17,因此 oom-killer 不会终止此进程。
但是我仍然不明白为什么内核认为它必须杀死一个进程并且不会继续释放一些缓存内存。
由于某种原因,我的一些工作正在被操作系统杀死。我需要调查为什么会发生这种情况。我运行的作业在它们自己的日志中没有显示任何错误消息,这可能表明 os 杀死了它们。没有其他人可以访问服务器。我知道 OOM 杀手,还有其他进程杀手吗?我在哪里可以找到这些东西的日志?
我正在编写一个模拟器,它依赖于生成(可能)非常大的问题域。由于数据无法放入 RAM,我使用 4 个四内存映射文件来保存它。这是一个在 64 位 Linux 上运行的 64 位应用程序,具有 8GB 的 RAM。
我的应用程序在多个线程中迭代内存映射并对它们执行读写操作。但是我的程序在启动后不久导致 OOM(没有发生颠簸):
[ 683.899682] Purging GPU memory, 25 pages freed, 12838 pages still pinned.
[ 683.899683] 50 and 0 pages still available in the bound and unbound GPU page lists.
[ 683.899732] Purging GPU memory, 0 pages freed, 12838 pages still pinned.
[ 683.899732] 50 and 0 pages still available in the bound and unbound GPU page lists.
[ 683.901441] gnome-shell invoked oom-killer: gfp_mask=0x240c0d0(GFP_TEMPORARY|__GFP_COMP|__GFP_ZERO), order=3, oom_score_adj=0
[ …Run Code Online (Sandbox Code Playgroud) 我在我的服务器上运行 Gentoo,我刚刚从内核 4.4.39 升级到 4.9.6,内核配置基本上没有改变。我的系统日志充满了如下错误报告:
[50547.483577] ksoftirqd/0: page allocation failure: order:0, mode:0x2280020(GFP_ATOMIC|__GFP_NOTRACK)
[50547.483605] CPU: 0 PID: 3 Comm: ksoftirqd/0 Not tainted 4.9.6-gentoo-r1 #2
[50547.483608] Hardware name: /LakePort, BIOS 6.00 PG 02/20/2009
[50547.483613] f5473bd0 c13e692e c17a9870 00000000 f5473c00 c10d03a7 c17a79dc 02280020
[50547.483626] f5473c08 f5473c10 c17a9870 f5473be4 f5282d37 00000008 00000000 00000030
[50547.483638] f5473cbc c10d0769 02280020 c17a9870 00000000 f5473c34 00000000 e5dca054
[50547.483652] Call Trace:
[50547.483670] [<c13e692e>] dump_stack+0x47/0x69
[50547.483679] [<c10d03a7>] warn_alloc+0xf7/0x120
[50547.483686] [<c10d0769>] __alloc_pages_nodemask+0x329/0xb40
[50547.483697] [<c1107114>] new_slab+0x2a4/0x460
[50547.483704] [<c1108e62>] ___slab_alloc.constprop.81+0x392/0x540
[50547.483713] [<c159fe11>] ? __build_skb+0x21/0x100 …Run Code Online (Sandbox Code Playgroud) 我使用 CentOS 7 内核 3.1.0
我知道 Linux 中有一个杀手叫做 oom 杀手,它杀死了一个使用过多内存的可用空间的进程。
我想配置它来记录活动,以便我可以检查它是否发生。我该如何设置?
谢谢,
当内存使用量达到某个值时,我正在尝试使用systemd 基础架构来终止内存泄漏服务。使用的配置文件是这样的:
[Unit]
Description="Start memory gobbler"
After=network.target
MemoryAccounting=true
MemoryHigh=1024K
MemoryMax=4096K
[Service]
ExecStart=/data/memgoble 8388600
Run Code Online (Sandbox Code Playgroud)
systemd版本是 237。但是,无论我在MemoryMax内核中设置什么,它都会按照自己的条件杀死进程,通常是当它的内存消耗几乎达到整个物理 RAM 时。我在没有交换的嵌入式系统上运行它。
有人在配置中看到明显的错误吗?也许还有一些我遗漏的其他设置。
out-of-memory ×10
linux ×5
memory ×3
swap ×3
linux-kernel ×2
arch-linux ×1
debian ×1
kill ×1
kubuntu ×1
kvm ×1
mmap ×1
qemu ×1
systemd ×1
ubuntu ×1