发现一个能有效避免内存不足导致的卡死的软件:earlyoom
Tofloor
poster avatar
duanyao
deepin
2017-06-29 05:58
Author
本帖最后由 duanyao 于 2019-7-30 19:45 编辑

网站: https://github.com/rfjakob/earlyoom

文档的解说已经很详细了,不过因为是英文,我简单介绍一下:
Linux 内核中的 oom-killer 严重不靠谱,往往触发得太迟。在它工作之前,系统往往已经没救了,或者用户已经被卡得失去耐心,按了重启键。
earlyoom 是个用户态服务,顾名思义它会较早的触发(默认条件是可用物理内存和交换分区都不足10%),杀掉内存消耗最多的进程,避免系统卡死。

我试了一下还是挺有效的,用 android-studio 编译一个大工程时,它先后杀掉了 chrome、 firefox、vs code,编译得以顺利完成。

建议 deepin 预装这个软件,我相信它能避免相当数量的卡死问题。

注:2017.9  deepin 已经收录了此软件,但没有预装,大家可以用 sudo apt install earlyoom 安装试用。安装后不必做什么,下次重启系统后自动生效。
注2:2019.7 deepin 15.9.2 - 15.11 稳定版仓库里没有此软件(预计v 20恢复),你可以装 debian 仓库里的: http://ftp.cn.debian.org/debian/pool/main/e/earlyoom/earlyoom_1.2-1_amd64.deb

补充:想了一下,还是把我这些年调查内存不足导致卡死的问题是做的笔记发上来。很凌乱,没什么条理,不过里面的很多链接应该是有参考价值的。
发上来的主要目的是说明:我并非是偶尔看到一个软件就兴冲冲的推荐了,这后面是有大量铺垫的。linux_memory_swap_thrashing.zip

linux_memory_swap_thrashing.zip


再补充:还没有经历过内存不足卡死,或者喜欢作死的小伙伴,可以试试这个小程序:

http://launchpadlibrarian.net/23372552/memory_overcommit.cc

来源是 ubuntu 的一个 bug 报告 https://bugs.launchpad.net/ubuntu/+source/linux/+bug/159356
下载后用 c++ 编译,运行。你需要输入每次分配的内存大小,单位 M,直接回车表示与上次相同。
如果剩余物理内存很多可以500M每步,剩余500M左右时改为100M每步,剩余100M左右时改为30M每步,而且不要太快。这很重要,如果最后阶段步子太大、太快,很容易被OOM killer 迅速杀掉。
剩余物理内存用系统监视器或free看就行。

在我的机器(机械硬盘)上,如果关闭 earlyoom (systemctl stop earlyoom),它几乎 100% 能卡死。之前我用的测试方法(浏览器开很多页面、开虚拟机、android-studio)太繁琐了,还是这个好。

为了从卡死中恢复,可以这么做:在运行 memory_overcommit.cc 之前,先修改 /etc/sysctl.d/99-sysctl.conf (也可能是同一目录下的其它名字),把 kernel.sysrq=0 (或其它值)改为 kernel.sysrq=1 ;然后重启系统,或执行 sudo sysctl kernel.sysrq=1 立即生效。

在卡死后,按下组合键 alt + sysrq + r  然后按 alt + sysrq + f ,这是为了手工执行 oom killer。oom killer 可能要延迟几秒钟才执行,所以不要急不可耐的反复按 alt + sysrq + f ,以免杀掉很多无辜进程。sysrq 就是 print screen 键。

Reply Favorite View the author
All Replies
5 / 5
To page
深圳市耀影科技有限公司
deepin
2021-05-02 21:23
#81
SamLukeYes

earlyoom 比较简单,我不确定它有没有提示的功能,但其他同类软件可能有。你说的“交换空间无用”,是不是因为 swappiness 设置得太小了?

 

 

SSD 配置16G,当物理内存跑到100的时候,立即卡死,根本不给你机会关闭程序啥的,等也没用,就是直接卡死啦,必须热启动,我试过很多次啦

 

 

Reply View the author
SamLukeYes
deepin
2021-05-03 00:07
#82
深圳市耀影科技有限公司

 

 

SSD 配置16G,当物理内存跑到100的时候,立即卡死,根本不给你机会关闭程序啥的,等也没用,就是直接卡死啦,必须热启动,我试过很多次啦

 

 

内存还有很多空闲的时候交换空间一点都没用是很正常的,内存快满的时候你看看交换空间的占用是不是突然开始上涨?当系统拼命地丢弃内存中的缓存并往交换空间里塞数据时,势必造成响应性下降甚至卡死,而 OOM killer 要等到内核认为真的没有其他措施可以挽救内存不足的形势时才会触发,通常在这之前用户就等得不耐烦并强制重启了。针对这种情况,主要有以下几种解决方案:

 

1、使用 zram 代替硬盘上的交换空间。在内存中创建压缩的块设备来作为交换空间,让内存可以存储更多数据,又不会在交换时因为读写硬盘而造成显著的性能下降。16 G 的内存已经很充裕了,如果不用于休眠的话,完全可以只用 zram 而不使用硬盘上的交换空间。如果要同时使用硬盘上的交换空间,也可以选择 zswap。zswap 是将内存的一部分作为准备写入交换空间的压缩缓存池,缓存池不够用了才会真正写入 swap,但内存紧缺的时候还是会不可避免地“卡死”,只是让“卡死”的阈值上升而已。注意 zram 和 zswap 不能同时使用,否则可能会造成一些别的问题,但 zram 和硬盘上的交换空间可以同时使用,只不过需要设置 zram 的使用优先于硬盘上的交换空间。

 

2、使用用户空间的 OOM killer,在内核的 OOM killer 启动之前采取正确的行动而避免出现让用户不耐烦的卡顿。

 

3、设置合适的 swappiness 数值。如果确实要用到硬盘上的 swap 空间,就要通过 snappiness 的值来正确地告诉内核使用交换空间交换内存脏页的代价到底有多大。如果将 swappiness 设置得太大,内核就会很倾向于将内存的脏页交换出去,在内存还很充裕的时候就可能造成肉眼可见的卡顿。如果将 swappiness 设置得太小,就会在内存严重不足的时候才拼命地开始交换,造成系统突然“卡死”,这样就还不如不使用交换空间了。合适的 swappiness 值既可以防止前一种情况的发生,又可以让后一种情况不容易发生。就我自己的 8 G RAM + 8 G SWAP 而言,默认的 swappiness 值 60 是有些偏大的,正常使用时即可出现肉眼可见的卡顿,调成 40 后用起来比较正常。如果你觉得太容易在内存不足的时候突然卡死,应该适当地把 swappiness 调大一点,让你在感觉到变卡的时候还有机会干预。

Reply View the author
5 / 5
To page