![Ubuntu 在发生 OOM 且没有发生抖动时怎么会变得无响应?](https://linux22.com/image/1165872/Ubuntu%20%E5%9C%A8%E5%8F%91%E7%94%9F%20OOM%20%E4%B8%94%E6%B2%A1%E6%9C%89%E5%8F%91%E7%94%9F%E6%8A%96%E5%8A%A8%E6%97%B6%E6%80%8E%E4%B9%88%E4%BC%9A%E5%8F%98%E5%BE%97%E6%97%A0%E5%93%8D%E5%BA%94%EF%BC%9F.png)
当我在 Ubuntu 18.10 上使用过多 RAM 时,GUI 会冻结。它停止对键盘和鼠标做出反应,除了硬重置计算机之外没有其他办法。
我认为这是因为系统已将 Gnome 二进制文件交换到磁盘,并且最终会将它们交换回来。但在观察到的时间范围内(约 20 分钟),这种情况从未发生过。
我尝试通过以下方式解决问题禁用交换(我宁愿丢失未保存的工作,也不愿丢失未保存的工作和必须重新启动 PC),并指示 OOM 终止程序根据以下方式终止触发 OOM 情况的进程:这个答案。然而,这并没有帮助。我尝试通过打开太多浏览器选项卡来使用大量内存,唯一发生的事情是系统再次变得无响应。
这怎么可能呢?除了抖动之外,还可能涉及其他什么机制?(真正的工程问题,不是咆哮)
我在这次实验中监控了系统统计数据,似乎 CPU 并未在 100% 负载下运行,因此这不是计算限制。此外,似乎在我有机会打开足够多的选项卡以触发 OOM 杀手之前,GUI 就冻结了。
我能想到的最好的理论是,GUI 库正在使用某种内存分配器,允许它们在内存非常少的情况下继续运行,要么使用某种替代交换机制,要么通过某种 CPU 密集型堆重新排列。否则我就不知道了。
对于这种行为有更好的解释吗?或者有解决方案吗?
编辑
我的交换性:
vm.swappiness = 60
我的记忆:
martin@martin-UX305UA:~$ free -h
total used free shared buff/cache available
Mem: 7.7G 5.5G 145M 993M 2.1G 975M
Swap: 2.0G 57M 1.9G
我的/etc/fstab
UUID=e0edf45b-903c-403f-b2c7-5e69b8b450da / ext4 errors=remount-ro 0 1
# /boot/efi was on /dev/sda1 during installation
UUID=0564-1C88 /boot/efi vfat umask=0077 0 1
/swapfile none swap sw 0 0
答案1
答案2
笔记:您确实需要添加更多 RAM,但我们会尝试这个……
每个系统都需要一个交换分区或 /swapfile。
删除 OOM 调整
将当前未使用的 2G /swapfile 更改为至少4G
调整 vm.swappiness
/交换文件
笔记:命令使用不当dd
可能导致数据丢失。建议复制/粘贴。
sudo swapoff -a # turn off swap
sudo rm -i /swapfile # remove old /swapfile
sudo dd if=/dev/zero of=/swapfile bs=1M count=4096
sudo chmod 600 /swapfile # set proper file protections
sudo mkswap /swapfile # init /swapfile
sudo swapon /swapfile # turn on swap
free -h # confirm 8G RAM and 4G swap
reboot # reboot and verify operation
确保此行在 /etc/fstab 中...
/swapfile none swap sw 0 0
vm.swappiness
在 中terminal
,尝试...
sudo sysctl vm.swappiness
# 查看原始值 (=60)
sudo sysctl vm.swappiness=80
# 改变 RAM 与交换比率
为了使...永久...
设置 vm.swappiness=80(基于 8G RAM 和 4G SWAP),这样...
sudo -H gedit /etc/sysctl.conf
# 编辑此文件
搜索现有vm.swappiness=
条目...
CTRL+f虚拟机.swappiness
如果发现,编辑也就是说
vm.swappiness=80
如果没有找到,添加
vm.swappiness=80
在文件末尾
保存编辑并退出 gedit
sudo sysctl -p