Ubuntu快速耗尽RAM,我的计算机开始冻结。 什么命令会解决这个问题?

当我在后台编译软件时,它经常发生在我身上,突然一切都开始变慢并最终冻结[如果我什么都不做],因为我已经用完了RAM和交换空间。

这个问题假设我有足够的时间和资源来打开Gnome终端,搜索我的历史记录,并执行一个sudo命令。

什么命令可以让我不必进行硬重启或任何重启?

根据我的经验,Firefox和Chrome使用的RAM比我前7台计算机的总和还多。 可能不仅如此,但我已经远离了我的观点。 您应该做的第一件事就是关闭浏览器 。 一个命令?

 killall -9 firefox google-chrome google-chrome-stable chromium-browser 

我已将最流行的浏览器绑定到一个命令,但显然如果你正在运行其他东西(或者知道你没有使用其中一个)只需修改命令。 killall -9 ...是重要的一点。 人们确实对SIGKILL (信号编号9)感到满意,但浏览器非常有弹性。 更重要的是,通过SIGTERM缓慢终止将意味着浏览器会进行大量清理垃圾 – 这需要额外的RAM – 这是您在这种情况下无法承受的。

如果您无法将其转换为已在运行的终端或Alt + F2对话框,请考虑切换到TTY。 Control + Alt + F2会让你进入TTY2,这应该允许你登录(虽然它可能很慢),甚至可以让你使用像htop这样的东西来调试问题。 我不认为我的内存已经耗尽了我无法达到的程度。

长期解决方案涉及购买更多RAM,通过远程计算机租用或不执行您当前正在执行的操作。 我会把错综复杂的经济论点留给你,但一般来说,RAM的价格很便宜,但如果你只需要一个爆发金额,每分钟或小时计费的VPS服务器是个不错的选择。

在启用了Magic System Request Key的系统上,按Alt + System Request + f (如果键盘上没有标记, System Request通常在Print Screen键上)将手动调用内核的内存杀手(oomkiller),试图挑选最糟糕的内存使用过程并将其杀死。 你可以做到这一点,如果你的时间可能比你描述的要短,系统即将开始(或者可能已经开始)颠簸 – 在这种情况下你可能并不关心到底是什么被杀,只是你结束了一个可用的系统。 有时这最终可能会杀死X,但是现在大多数情况下选择一个糟糕的过程比以前更好。

与其他答案相反,我建议您在执行此操作时禁用交换。 虽然swap使系统以可预测的方式运行,并且通常用于增加访问磁盘的应用程序的吞吐量(通过逐出未使用的页面以允许磁盘缓存空间),在这种情况下,听起来您的系统正在减速由于太多积极使用的内存被强行驱逐以进行交换,因此无法使用。

我建议在执行此任务时完全禁用交换,以便内存杀手在RAM填满后立即执行操作。

替代方案:

  • 通过将交换分区放在RAID1中来提高交换的读取速度
    • 或RAID0,如果您感觉有风险,但如果您的任何磁盘出现故障,这将导致大量正在运行的程序。
  • 减少并发构建作业的数量(“更多核心=更多速度”,我们都说,忘记它需要线性收费RAM)
  • 这可能是双向的,但尝试在内核中启用zswap 。 这会在页面发送到交换之前压缩页面,这可能提供足够的摆动空间来加速您的计算机。 另一方面,它可能最终成为它所做的额外压缩/解压缩的障碍。
  • 调低优化或使用其他编译器。 优化代码有时会占用几千兆字节的内存。 如果你打开LTO,你也会在链接阶段使用大量的RAM。 如果所有其他方法都失败了,您可以尝试使用轻量级编译器(例如tcc )编译项目,但代价是编译产品的运行时性能略有下降。 (如果您正在进行开发/调试,这通常是可以接受的。)

您可以使用以下命令(如果需要,可以重复使用)以使用系统上的最大RAM来终止进程:

 ps -eo pid --no-headers --sort=-%mem | head -1 | xargs kill -9 

附:

  • ps -eo pid --no-headers --sort=-%mem :显示所有正在运行的进程的进程ID,按内存使用情况排序
  • head -1 :只保留第一行(使用最大内存的进程)
  • xargs kill -9 :杀死进程

在德米特里的准确评论后编辑:

这是一个快速而肮脏的解决方案,应该在没有敏感任务运行时执行(您不想kill -9任务kill -9 )。

在运行资源消耗命令之前,您还可以使用setrlimit(2)系统调用,可能使用bash shell内置的ulimit (或zsh中内置的limit ),特别是对于RLIMIT_AS使用-v 。 然后,太大的虚拟地址空间消耗(例如,使用malloc(3)使用的mmap(2)或sbrk(2 ) )将失败( errno(3)为ENOMEM )。

然后,在冻结系统之前,它们(即在你输入ulimit之后shell中的饥饿进程)将被终止。

另请阅读Linux Ate My RAM并考虑禁用内存过量使用 (通过以root身份运行命令echo 0 > /proc/sys/vm/overcommit_memory ,请参阅proc(5) …)。

当我在后台编译软件时,这经常发生在我身上

在这种情况下,像“killall -9 make”(或者你用来管理编译的任何东西,如果不是make)。 这将进一步停止编译过程,将SIGHUP从它启动的所有编译器进程(希望它们也会停止),作为奖励,假设您正在编译为您记录的同一用户,则不需要sudo在…中。 并且由于它会导致您的问题的实际原因而不是您的Web浏览器,X会话或随机的某个进程,它不会干扰您当时在系统上执行的任何其他操作。

为自己创建更多交换。

以下将添加8G交换:

 dd if=/dev/zero of=/root/moreswap bs=1M count=8192 mkswap /root/moreswap swapon /root/moreswap 

它仍然会很慢(你正在交换),但你实际上不应该用完。 现代版本的Linux可以交换到文件。 这些天关于交换分区的唯一用途是hibernate你的笔记本电脑。

在短时间内获得大量空闲RAM的一种方法是使用zram ,它创建一个压缩的RAM磁盘并在那里交换。 使用任何一半不错的CPU,这比常规交换要快得多,并且压缩率非常高,许多现代RAM都像Web浏览器一样。

假设您已安装并配置了zram,则只需运行即可

 sudo service zramswap start 

人们可以做的另一件事是通过这个命令释放内存页面缓存:

 echo 3 | sudo tee /proc/sys/vm/drop_caches 

来自kernel.org文档(重点补充):

drop_caches

写入此内容将导致内核删除干净的缓存,以及可重命名的slab对象(如dentries和inode)。 一旦被丢弃,他们的记忆就变得自由

要释放pagecache:echo 1> / proc / sys / vm / drop_caches要释放可回收的slab对象(包括dentries和inode):echo 2> / proc / sys / vm / drop_caches释放slab对象和pagecache:echo 3> / proc / SYS / VM / drop_caches

这是一种非破坏性操作 ,不会释放任何脏物。 为了增加此操作释放的对象数,用户可以在写入/ proc / sys / vm / drop_caches之前运行`sync’。 这将最大限度地减少系统上脏对象的数量,并创建更多要删除的候选对象。

sudo swapoff -a将禁用交换,如果系统内存不足,内核会自动终止具有最高分数的进程。 我使用这个,如果我知道我会运行一些RAM很重的东西,如果它失去控制,我宁愿杀死它,而不是让它进入交换并永远陷入困境。 之后使用sudo swapon -a重新启用它。

稍后,您可能需要查看交换设置。 听起来你的交换与根分区在同一个磁盘上,这会在你点击交换时减慢你的系统速度,所以如果可以,请避免这样做。 此外,在我看来,现代系统通常配置太多交换。 32GiB RAM通常意味着默认分配32GiB交换,就好像你真的想把32GiB放入交换空间一样。

你说“在后台编译”。 你在前台做什么? 如果您使用Eclipse或其他资源较多的IDE进行开发,请检查控制台中是否所有内容都已正确终止。

开发环境通常允许启动正在开发的多个进程,这些进程也可能在您不再对它们感兴趣之后(在调试器中,或者只是没有正确完成)。 如果开发人员没有注意,那么在白天可能会累积数十个被遗忘的进程,使用多个千兆字节。

检查是否应终止在IDE中终止的所有内容。