多年来,我的操作系统的OOM 杀手无法正常工作并导致系统冻结。
当内存使用率非常高时,整个系统往往会“冻结”(实际上:变得非常慢)几个小时甚至几天,而不是杀死进程来释放内存。
我记录的最长期限是在辞职以进行重置之前的 7 天。
当即将达到 OOM 时,iowait非常非常高(~ 70%),然后变得不可测量。
该工具:iotop表明每个程序都以非常高的吞吐量(每几十 MB/秒)从我的硬盘驱动器中读取。
那些程序在读什么?
- 目录层次结构?
- 可执行代码本身?
我现在不知道。
[已编辑] 在我写这条消息时(2017 年),我使用的是最新的 ArchLinux (4.9.27-1-lts),但几年前就已经遇到了这个问题。
我在各种 Linux 发行版和不同的硬件配置中遇到过同样的问题。
目前(2019 年),我使用的是最新的 Debian 9.6 (4.9.0) 我有16 GB的物理内存,一个安装了我的操作系统的 SSD,而不是任何交换分区。
由于我拥有的 ram 数量,我不想启用交换分区,因为它只会延迟问题的出现。
此外,由于 SSD 交换过于频繁,可能会缩短磁盘的使用寿命。
顺便说一下,我已经尝试过使用和不使用交换分区,事实证明它只会延迟问题的出现,而不是解决方案。
对我来说,问题是由于 Linux 从缓存中删除了重要数据,这导致系统冻结,因为它每次都必须从硬盘驱动器读取所有内容。
我什至想知道 Linux 是否不会删除正在运行的程序的可执行代码页,这可以解释为什么通常不读取大量数据的程序在这种情况下会这样做。
我已经尝试了几件事,希望能解决这个问题。
一种是设置/proc/sys/vm/min_free_kbytes为1000000(1 GB)。
因为这1 GB应该是空闲的,所以我认为这块内存会被 Linux 保留来缓存重要数据。
但它没有奏效。
另外,我认为补充一点很有用,即使它在理论上听起来不错,但通过定义 …
根据内核文档:
This control is used to define how aggressive the kernel will swap
memory pages. Higher values will increase aggressiveness, lower values
decrease the amount of swap.
Run Code Online (Sandbox Code Playgroud)
然而,这有点模糊。我试图弄清楚参数最终控制什么。我知道它会调整内核尝试换出页面的积极程度,但它会影响内核代码中的哪些决策过程?
它是否会在内核将其换出之前调整页面必须在多长时间前被访问?如果是这样,默认值 60 代表什么?增加/减少 1 会改变多少(公式会很好)?
或者它是否根据访问频率换出页面?
或者是其他东西?