问题描述
今天早上,按照惯例开始完成之前的半成品博客,内容是描述 modpost 的原理。描述的过程中,我同时执行一些命令来采集输出,我写得正爽的时候,执行了 make -j 命令编译后系统卡住了,之前遇到过一次,应该是 oom 了。
不过也没啥大不了的,等几分钟就会恢复,之前遇到的时候貌似对我没有啥影响,等了几分钟,系统恢复正常后,发现 firefox 重启了!恢复之前的 session 后我发现我之前写的博客内容全部丢失了,这就不好玩了!
oom 是啥?
oom 是 out of memory 的简称,是系统内核耗尽时的一种恢复机制,它会按照一些策略选取进程杀死以释放空间。
我的 firefox 进程被 oom 策略选中后被杀死,而且我之前没有保存草稿,数据就这样丢失了。
我查看 dmesg 信息找到了下面这些内容:
[212840.264294] Out of memory: Kill process 29823 (gnome-shell) score 4 or sacrifice child
[212840.264339] Killed process 29823 (gnome-shell) total-vm:3794112kB, anon-rss:684kB, file-rss:0kB, shmem-rss:0kB
[212840.272901] oom_reaper: reaped process 29823 (gnome-shell), now anon-rss:0kB, file-rss:0kB, shmem-rss:0kB
这里明确表示触发了 oom,然后 oom 选中了 gnome-shell 进程杀死,释放内存空间。也许我该庆幸系统没有一直死锁,这是 oom 经常遇到的问题,在一些情况下当系统检测到了 oom 之后已经为时已晚,这样系统会整个挂死,如果有看门狗,应该会在既定的时间后重启。
用户态 early-oom-killer 可以用来解决这个问题,不过它不是这里要说明的重点,直接跳过。
为什么 firefox 会躺枪呢?
oom 杀死进程没有什么大不了的,我的问题在于为什么 firefox 也会被杀掉呢?dmesg 不是显示 gnome-shell 被杀了吗?
我并不是在一个 shell 中启动的 firefox,而是通过系统启动项目启动的,firefox 是怎样跟一个 gnome-shell 挂上钩的呢?
pstree 查看进程信息,得到了如下内容:
systemd-+-ModemManager---2*[{ModemManager}]
|
|-gdm3-+-gdm-session-wor-+-2*[gdm-session-wor---2*[{gdm-session-wor}]]
| | |-gdm-x-session-+-Xorg---3*[{Xorg}]
| | | |-gnome-session-b-+-evolution-alarm---5*[{evolution-alarm}]
| | | | |-gnome-shell-+-firefox-esr-+-Web Content---46*[{Web Content}]
| | | | | | |-Web Content---51*[{Web Content}]
| | | | | | |-Web Content---32*[{Web Content}]
| | | | | | |-Web Content---48*[{Web Content}]
| | | | | | `-70*[{firefox-esr}]
| | | | | |-guake-+-bash-+-less
| | | | | | | `-pstree
| | | | | | `-3*[{guake}]
| | | | | `-21*[{gnome-shell}]
从上面的进程树中可以看出,gnome-shell 是 firefox-esr 的父进程,有了这个信息我就明白了,应该是杀了父进程带来的影响,而且这个父进程不只是父进程这么简单,应该跟 session 有关。
我的笔记本电脑的内存配置
我的电脑的内存信息如下:
[longyu@debian-10:10:05:31] ~ $ free -h
total used free shared buff/cache available
Mem: 7.6Gi 1.6Gi 3.4Gi 197Mi 2.6Gi 5.5Gi
只有 8G 可以用,算比较少了,make -j 创建了多个线程的时候很容易耗尽内存!