多年来,我的操作系统的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 保留来缓存重要数据。
但它没有奏效。
另外,我认为补充一点很有用,即使它在理论上听起来不错,但通过定义 …
至少在GNU bash 版本 4.3.42 x86_64 && GNU bash 版本 4.3.11 x86_64 上发生
我使用sleep & wait $!而不是简单的sleep来获得sleep信号的可中断性(如SIGUSR1)。但是wait当您运行以下命令时,bash-builtin 的行为似乎很奇怪。
cat <(
trap 'echo SIGUSR1' SIGUSR1;
echo $BASHPID;
while :;do
sleep 1 &
wait $!;
echo test;
done
)&
Run Code Online (Sandbox Code Playgroud)
kill -10 /the pid of the subshell, printed by the previous command/
Run Code Online (Sandbox Code Playgroud)
^C (ctrl + C)
Run Code Online (Sandbox Code Playgroud)
然后,我得到了以 100% 消耗 CPU 的子外壳。
pkill -P $(pgrep -P $$)
Run Code Online (Sandbox Code Playgroud)
你知道为什么会发生这种行为吗?
注意 …