OOM 机制
“我们从OOM的角度来帮大家提高一点内存方面的知识,虽然不能说帮助人们来完全解决内存问题,但是也能从一个侧面来提高大家分析内存问题相关的能力。”
这是关于 Linux 内核的学习笔记,重点要了解 OOM 这块的相关知识点。
1 相关概念
1.1 同步回收 VS 异步回收
- 同步回收:直接调用函数进行回收
- 异步回收:通过唤醒回收线程 kswapd 处理
1.2 内存规整
- 将不连续的物理页变成连续的物理页,目的在于减少页之间的外部碎片,空出"更大"的物理内存
1.3 文件页和匿名页
- 文件页:有后备存储文件,对应text data段上的页帧
- 匿名页:swap 作为后备存储,对应堆栈上的页帧
1.4 页帧回收
- 如果内存规整分配不到内存,使用页帧回收进行分配。首先考虑 clean 的文件页,如果可释放的空间不足以满足,其次考虑 dirty 的文件页或者匿名页
1.5 OOM Killer
- 如果页帧回收也分配不出内存,剩下一个方式就是 OOM Killer 了。通俗来讲是查杀进程来释放内存资源
1.6 kswapd 线程
- 异步回收线程 kswapd,这个线程被周期性唤醒,来执行内存回收任务。每个 node 会有一个专用的 kswapd 线程
- kswapd 执行完成后会唤醒 kcompactd 执行,进行内存规整将 free 内存尽量连成一片
2 理解OOM
- 内存耗尽的意思,这里根据虚拟内存空间和物理内存空间,有两个区分:虚拟内存 OOM 和物理内存 OOM
- 虚拟内存 OOM:用户态进程申请内存,但还没有使用。实际上没有分配物理内存和映射页表,指虚拟内存空间
- 物理内存 OOM:用户和进程有分配物理内存的场景,如果物理内存不足也会 OOM
2.1 内存分配策略
对于虚拟内存 OOM, Linux 内核提供三种策略,决定最多可分配内存空间大小
#define OVERCOMMIT_GUESS 0
#define OVERCOMMIT_ALWAYS 1
#define OVERCOMMIT_NEVER 2
2.2 内存管理策略
对于物理内存 OOM,当系统发现没有足够的物理内存时,各种手段(内存规整,页帧回收,kswapd线程)用尽,会使用 OOM Killer 来查杀进程来释放空间
3、在android中实现了lmkd进程,它会在OOM之前查杀进程,LMK有依赖OOM Killer的部分,但运行起来是独立的(共同作用回收内存,LMK在前,OOM Killer在后)