一、什么时候回收内存?
1、直接内存回收
有新的大块内存分配请求,但是剩余内存不足。这个时候系统就需要回收一部分内存,进而尽可能地满足新内存请求。
2、定期扫描回收(kswapd)
操作系统内核线程kswapd定期进行回收内存,并通过设定三个内存阈值来衡量内存的使用情况,分别是
- 页最小阈值(pages_min)
- 页低阈值(pages_low)
- 页高阈值(pages_high)
kswapd定期扫描内存的使用情况,并根据剩余内存落在这三个阈值的空间位置,进行内存的回收操作。
1)free < pages_min:说明进程可用内存都耗尽了,触发直接内存回收,此时只有内核才可以分配内存
2)pages_min<free<pages_low:说明内存压力比较大,剩余内存不多了。这时 kswapd会执行内存回收,直到剩余内存大于高阈值为止。
3)pages_low<free<pages_high:说明内存有一定压力,但还可以满足新内存请求。
4)free>pages_high:说明剩余内存比较多,没有内存压力。
二、回收的方式
1、对于缓存和缓冲区的内存回收
1)对文件页的回收,直接回收缓存
2)对脏页的回收,写回磁盘后再回收。
2、基于 Swap 机制,回收不常访问的匿名页(应用程序动态分配的堆内存),通过 Swap 机制,把它们写入磁盘后再释放内存。
3、oom机制进行回收
三、相关参数调整
1、内核参数vm.swappiness,决定回收缓存或swap机制回收内存的倾向
取值范围是 0-100,
数值越大,越积极使用 Swap,也就是更倾向于回收匿名页;
数值越小,越消极使用 Swap,也就是更倾向于回收文件页。
0不代表不使用swap,当剩余内存 + 文件页小于页高阈值时,还是会发生 Swap。
2、内核参数vm.min_free_kbytes,调整内存水位
pages_min = min_free_kbytes换算为page单位,
pages_low = pages_min*5/4
pages_high = pages_min*3/2
3、oom机制
1)vm.panic_on_oom:
- 0:当内存耗尽时,内核会触发OOM killer杀掉最耗内存的进程。
- 1:表示关闭此功能,内核直接panic
2)vm.oom_kill_allocating_task
- 0:内核检查每个进程的分数,分数最高的进程将被kill掉
- 1:内核将kill掉当前申请内存的进程