内存页类型🐟页面回收

参考博客

不同页类型

文件页

内核缓存的磁盘数据、缓存的文件数据都叫做文件页。回收干净页时直接释放即可;回收脏页时要先讲修改内容写回磁盘对应的文件/数据块,接着才能释放内存

匿名页

这部分内存没有实际载体,比如堆、栈数据。这部分内存后续可能还要再次访问,所以不能直接释放内存,它们的回收是通过Linux的SWAP机制。

LRU(Least recently used)算法

优先回收不常使用访问的内存,其维护了两个双向链表

  • active list: 存放最近被访问过「活跃」的内存页;在内存页被访问第二次的时候,才将其从非活跃链表加载到活跃链表,以解决「缓存污染」导致的页面缓存命中率🎯下降的问题
  • inactive list: 存放很少被访问「非活跃」的内存页;读取磁盘数据时,将预读页加到这个链表,以解决「预读失效」造成的页面缓存命中率🎯下降的问题

传统的LRU算法只有一个链表,最近使用的页链表节点在链表的头部

内存回收两种方式

  • 注意这里的内存是指物理内存
  • 干净文件页的回收是效率最高的,因此一般设置此种倾向较高
  • 尽早触发kswapd进行异步的内存回收;避免进程频繁的直接内存回收
  • 两种方式的触发是根据系统「剩余空闲内存数值」及「预设指标」的大小关系进行的

后台回收

唤醒内核线程kswapd进行异步内存回收

直接回收

当前进程直接进行内存回收:同步

OOM

如果前两种方式后,剩余内存还是不足,那么系统会根据某种算法,选择占用「占用物理内存」最高的进程,把它杀掉,并释放对应的内存

如何保护一个进程不被OOM机制杀掉?

OOM会扫描系统中可杀掉进程,并「进行打分」,得分高的进程被优先杀掉。分数计算取决于

  • 进程已经使用的物理内存页面数
  • 每个进程的OOM校准值:oom_score_adj - [-1000, 1000],每个进程默认值为0
  • score = already_used + oom_socre_adj * total_pages / 1000
    因此可以通过调整每个进程的OOM校准值,降低其被杀掉的概率。

内存页类型🐟页面回收
http://example.com/2024/09/08/嵌入式-开发/内存页类型🐟页面回收/
作者
Cyokeo
发布于
2024年9月8日
许可协议