linux building fresh packages卡住_数据段


我在《linux 启蒙——安装》一文中提到初学 Linux 可以不设 swap 分区。可是转眼就在网上看到了一个因为没设 swap 分区导致系统卡死的问题。

这个问题简单来说就是关闭 swap 功能(sudo swapoff -a),打开浏览器,不断地在新标签打开网页。观察内存占用情况。当内存占用达到一定程度的时候,系统就会卡死,硬盘灯会狂闪,甚至连鼠标都无法移动。

提问的人是 Artem S. Tashkinov,他说道:

I think that's not how the system should behave in this situation.

确实,操作系统负有资源管理之责任,理应妥善处理内存不足的情况。出现这个问题确实有点匪夷所思了。

我不是内核的专家,解答不了这个问题。但 Chris Siebenmann 专门发了一篇文章分析这个问题。在这里我就整理编译一下分享给大家。

包括 Linux 在内,UNIX 系统以(page)为单位管理内存。内存页大致可分为匿名页(anonymous pages)和文件页(file-backed pages)两类。如果程序向系统动态申请内存(比如通过调用 malloc()函数)或者修改程序全局变量,系统就会映射匿名页;如果程序通过 mmap方式读写磁盘文件,系统就会映射文件页。还有就是程序的代码段只读数据段也是通过文件页映射到内存的。

对程序而言,这两种页在使用上是没有区别的。可对操作系统而言就大不一样了。

如果内存不够用了,操作系统就会尝试回收内存。对于文件页,很简单,直接写回磁盘;对于匿名页,则只能写到 swap 分区。如果系统没有 swap 分区或者关闭了 swap 功能,那操作系统就没法回收匿名页占用的内存了。这个时候唯一能做的就是尽量将文件页写回文件,好释放对应的内存。这个时候,好多程序的代码段和只读数据段内容就会被反覆释放和加载,硬盘会狂闪,系统会卡住。

以前的程序代码都不长,相对而言系统的内存足够大,所以这个问题不明显。现在不一样了,像 Chome 和 Firefox 这样的程序本身体积就很大,再加上依赖的动态库,使用的时候会引入大量的文件页。系统内存吃紧的时候这会放大卡顿的问题。