麻烦请教大家一个问题,有台机器,没有使用 swap ,但是内存不够用了,,cached 有点高,导致磁盘 io 读会高,,我理解 cached 是读缓存,如果不够了,就需要不断从内存换出到磁盘,导致磁盘 io 高,这也理解对吗?

遇到了同样问题,大数据 boy 吗?

主要还是看磁盘性能;
可以验证是不是不管内存够不够,都高还是怎么样.

我的理解是:会

内存的作用之一就是共享文件内容,物理内存放不下,虚拟内存又没有,那还怎么共享,不得每次都读硬盘啊

分情况。

大多数由系统进行内存管理的,无论 Linux 还是 Win 的 app ,都会。

但如果是程序自己进行内存管理的,那得看程序是怎么设计的了。

不是大数据

linux 有个 swap 分区, swap 就是一个文件,在磁盘上, 内存不够会溢出到 swap , 溢出 这个过程就是写磁盘 。会导致磁盘 IO 高,有了 swap 程序不会立即崩溃 ,只是会响应慢。

反之 ,关掉 swap ,就不会写磁盘 。IO 不会高,其中内存不够程序直接崩溃,崩溃后继续被守护拉起,继续循环崩溃,如果时间间隔过短,频繁开启进程会导致 CPU 高。

linux 跟 windows 不一样,有多少内存吃多少。会用空闲的内存缓存文件句柄,常访问的文件等等,那个 cache 就是缓存的句柄,文件,关掉 swap 情况下,是在内存中,这个缓存跟磁盘 IO 影响比较小,读一次就被缓存了。

也就是内存不足就会 oom kill 掉程序。磁盘读 io 高可能是有程序在读文件。

禁了 swap 就不会,内存用光直接 OOM 杀死程序

这个 IO 应该是进程自身要读写文件产生的,与操作系统无关。虽说要读的文件不在 cache 中就产生磁盘 IO ,但在我看来这属于是从一个优化场景降级为正常场景。

你分析是对的。
比如 进程 elf 本身、加载的.so 共享库,它们的代码段等内容在内存中 是“有 backing file 的内存页”,并且它都是 readonly 的。

当内存不足时,Linux 内核会直接从 page cache 中扔掉这类页面。因为可以加载回来,并且由于是 read only 内存页,它与外部存储器上的内容是等价的。抛弃这些页面并不会造成数据上出现问题。

然而,当近程被调度,执行代码时执行到了这块被扔掉的代码,Linux 内核没有办法,只能阻塞进程(表现为进程状态为 D ),然后从外部存储中把这些数据再加载回来。

再加载回来时,也需要内存页,那就需要把其它进程的某些内存页扔掉。而其它进程被调度到时,又要继续循环,扔掉一些内存页。

最终恶性循环造成磁盘 IO 占用高,CPU 占用表现为%iowait 占用过高。

#10 不止 readonly 的啊,只要是有 ”backing file“的 writable 内存页都可以被交换到 swap 里。这不就是经典的“脏页”么

6# “linux 跟 windows 不一样,有多少内存吃多少。”Windows 一样

那位老哥说不定生活在二十年前。

句柄在 linux 下是什么意思

文件描述符吧。Linux 应该不缓存这玩意吧,只有一 buffer cache 和一 file cache 。不过据说新内核把两者统一了。再吐槽一下垃圾翻译,谁 tm 翻译的文件句柄

#15 不过 linux 有 dentry cache 之类的东西。另外 buffer 和 page cache 已经统一了十几年了…

我也遇到了

我的场景是容器 oom ,和这个类似
github.com/docker/for-linux/issues/670
楼主倒是提醒了我
unix.stackexchange.com/questions/225129/why-is-io-so-high-when-almost-out-of-memory
serverfault.com/questions/255661/linux-oom-disk-i-o-also-swap-what-is-it-good-for

这是没有 swap 的情况。有 swap 的情况下,部分页面会与 swap 建立 backing file 关系。建立好关系之后,会一样处理。

可以把 swap 设置为 1 ,这样能达到监控效果,同时程序不会 crash 掉

内存压力大时,kswapd0 会回收 page cache 中的一些脏页,这个过程应该会根据脏页水位在系统不太忙时异步去做,一般不会造成 IO 高的问题。如果 IO 高了,情况可能很复杂,感觉挺难分析的。

内存不够,在有 GUI 的情况下就直接“死机”了。

内存不够,如果没虚拟内存机制,那么进程将会直接崩溃被杀死.
所以你希望是进程直接消失还是磁盘 io 高点进程继续活着好呢?