当我在后台编译软件时,这种情况经常发生,突然一切都开始变慢并最终冻结(如果我什么都不做),因为我的 RAM 和交换空间都用完了。
这个问题假设我有足够的时间和资源来打开 Gnome 终端,搜索我的历史记录并执行一个sudo
命令。
什么命令可以让我免于进行硬重启或任何重启?
答案1
根据我的经验,Firefox 和 Chrome 占用的内存比我之前 7 台电脑的总内存还要多。可能还不止这些,但我离题了。你应该做的第一件事是关闭浏览器。命令?
killall -9 firefox google-chrome google-chrome-stable chromium-browser
我把最流行的浏览器绑定到一个命令中,但显然如果你正在运行其他东西(或者知道你没有使用其中之一),只需修改命令即可。这killall -9 ...
是重要的一点。人们确实对(信号编号 9)感到疑惑,SIGKILL
但浏览器极其弹性。更重要的是,通过缓慢终止SIGTERM
将意味着浏览器会进行大量清理垃圾 — 这需要大量额外的 RAM — 而这是您在这种情况下无法承受的。
如果您无法将其放入已运行的终端或Alt+F2对话框中,请考虑切换到 TTY。Control++将带您进入 TTY2,它应该允许您登录(尽管速度可能很慢),甚至应该允许您使用类似的东西Alt来调试问题。我想我从来没有耗尽 RAM 到无法启动的地步。F2htop
htop
长期解决方案包括购买更多 RAM、通过远程计算机租用 RAM 或不做你现在正在做的事情。我将把复杂的经济论据留给你,但一般来说,RAM 买起来很便宜,但如果你只需要大量内存,按分钟或小时计费的 VPS 服务器是一个不错的选择。
答案2
在启用了魔法系统请求键的系统上,按Alt + System Request+ f(如果键盘上没有标记,System Request通常位于Print Screen键上)将手动调用内核的内存不足终止程序 (oomkiller),它会尝试选择内存使用率最高的违规进程并将其终止。如果您的时间可能比您描述的要少,并且系统即将开始(或可能已经开始)抖动,您可以执行此操作 - 在这种情况下,您可能不关心到底要终止什么,只要您最终得到一个可用的系统即可。有时这可能会导致 X 终止,但现在大多数时候它在选择不良进程方面比以前要好得多。
答案3
与其他答案相反,我建议您在执行此操作时禁用交换。虽然交换可让您的系统以可预测的方式运行,并且通常用于增加访问磁盘的应用程序的吞吐量(通过驱逐未使用的页面为磁盘缓存留出空间),但在这种情况下,听起来您的系统速度正在减慢到无法使用的水平,因为太多活跃使用的内存被强制驱逐到交换。
我建议在执行此任务时完全禁用交换,这样内存溢出杀手就会在 RAM 填满时立即采取行动。
替代解决方案:
- 将交换分区放入 RAID1 中,以提高交换的读取速度
- 或者如果您觉得有风险,也可以使用 RAID0,但如果任何磁盘发生故障,这将导致大量正在运行的程序瘫痪。
- 减少并发构建作业的数量(我们都说“更多核心=更快速度”,但却忘记了这会对 RAM 造成线性影响)
- 这两种方法都行得通,但请尝试
zswap
在内核中启用。这会在页面发送到交换之前对其进行压缩,这可能会提供足够的回旋余地来加快您的机器速度。另一方面,它最终可能会成为一种障碍,因为它会进行额外的压缩/解压缩。 - 降低优化或使用其他编译器。优化代码有时会占用几 GB 的内存。如果启用了 LTO,链接阶段也会使用大量 RAM。如果其他方法都失败了,您可以尝试使用更轻量的编译器(例如)编译项目
tcc
,但编译后的产品运行时性能会略有下降。(如果您出于开发/调试目的这样做,这通常是可以接受的。)
答案4
在运行消耗资源的命令之前,您还可以使用设置限制(2)系统调用,可能与ulimit
你的 bash shell 的内置命令(或limit
zsh 中的内置命令),尤其是-v
for RLIMIT_AS
。然后虚拟地址空间消耗太大(例如mmap(2)或者sbrk(2)由使用malloc(3))将会失败(错误码(3)存在ENOMEM
)。
然后它们(即您输入之后,shell 中的饥饿进程ulimit
)将在冻结您的系统之前终止。
另请阅读Linux 占用了我的内存并考虑禁用内存过量使用(以 root 身份运行命令echo 0 > /proc/sys/vm/overcommit_memory
,请参阅进程(5)...)。