kernel的内存泄漏和native类似,不过原生的kernel就有集成内存回收和调试的功能。
kernel设计的原则是不到万不得已就不做任何事情,比如内存尽量分配出去使用,实在没有内存才启动回收。
网络有些文章讲解内存回收机制,可以参考:
内存回收机制
内存水位
对于内存是否回收是针对每个zone考量的。而考量的参数有high、low和min,各个zone各一套,这3个参数的关系如下:
- high > low > min
- min以下的内存属于系统的保留内存,用以满足特殊使用,不会分配给用户态的申请
当内存可用量小于low时,kernel开始启动内核线程kswapd进行内存回收,当内存可用量降至min时,kernel直接进行直接回收(direct reclaim),即直接在应用程序的进程上下文中进行回收,再用回收上来的空闲页满足内存申请,因此会阻塞应用程序,带来一定的响应延迟,如果回收不到则会启动oom-killer通过杀程序回收内存,如果还是回收失败则会触发OOM。
kernel要么不回收内存,一旦开始回收内存,它将持续回收一直到可用的内存大于high。参考下图:
kswapd
kswapd是内存回收进程,且每个zone有一个,会定期监控和回收内存。
OOM killer
实在要不到内存时,则启动oom killer,就是通过杀死比较肥的进程来回收内存。
如何评判要杀哪个进程呢?就是要给进程打分,根据分数排行,选择杀哪个进程,这里有篇文章讲解,请参考:
隐含的规则
too small to fail
用GFP_KERNEL申请低阶(< 3) 连续内存(8 个连续页)分配的话,就不会返回NULL,如果不够内存,会通过回收机制回收,如果回收不到直接panic。