linux内核中内存反碎片技术

Posted 为了维护世界和平_

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了linux内核中内存反碎片技术相关的知识,希望对你有一定的参考价值。

目录

一、反碎片技术引进

二、虚拟可移动区域

三、内存碎片整理

3.1 整理算法:

3.2 内存碎片整理优先级:

3.3 碎片整理的开始时机

3.4 碎片整理结束条件

3.5 具体使用方式


        内存碎片分为内部碎片和外部碎片,内部碎片指内存页里面的碎片,外部碎片指空闲的内存页分散,很难找到一组物理地址连续的空间内存页,无法满足超过一页的内存分配请求。

一、反碎片技术引进

  • 2.6.23版本引入了虚拟可移动区域
  • 2.6.23版本引入了成块回收,3.5版本废除,被内存碎片整理技术取代
  • 2.6.24版本引入了根据可移动性分组技术,把物理页分为不可移动物理页,可移动物理页和可回收页三种类型
  • 2.6.35版本,引入了碎片整理技术。

二、虚拟可移动区域

        可移动区域(ZONE_MOVABLE)是一个伪内存区域,基本思想很简:把物理内存分为两个区域,一个区域用于分配不可移动的页,另一个区域用于分配可移动的页,防止不可移动的页向可移动的页区域引入碎片。

        区域大小设置:

  1. 内核引导参数kernelcore=xx指定不可移动区域大小,也可使用kernelcore=mirror指定使用镜像内存,其他区域作为可移动区域。
  2. 内核引导参数movablecore=xx指定可移动区域大小。
  3. 如果同时设置kernelcore,movablecore,那么不可移动区域大小取kernelcore和(物理内存大小-movablecore)的最大值。

        在NUMA系统上,宏CONFIG_MOVABLE_NODE,并指定内核引导参数movable_node,那么忽略内核引导参数kernelcore和movablecore,所有可以热插拔的物理内存都可作为移动区域。

        可移动区域 没有包含任何物理内存,是虚拟的内存区域。可移动区域借用最高内存区域的内存,32位系统通常是高端内存区域(ZONE_HIGHMEM),64位系统最高内存区域通常是(ZONE_NORMAL)。

三、内存碎片整理

        从内存区域的底部扫描已分配的可移动页,从内存区域的顶部扫描空闲页,把底部的可移动页移动到顶部空闲页,在底部形成连续的空闲页。

3.1 整理算法:

  1. 首先从内存区域底部向顶部以页块为扫描单位,在页块内部起始页向结束页扫描,把这个页块里面的可移动页组成一条链表;
  2.  然后从内存区域顶部向底部以页块为单位扫描,在页块内部从起始页向结束页扫描,把空闲页组成一条链表;
  3. 最后把底部的可移动页的数据复制到顶部的空闲页,修改进程的页表,把虚拟页映射到新物理页。

     

        假如有16个页,白色表示空闲页。这个内存区域已经碎片化,最大的连续页是两页。从这个区域内存分配3页就会失败,甚至分配两页也会失败,因为连续的空闲页的起始地址没有对齐到两页的整数倍。

3.2 内存碎片整理优先级:

  • 完全同步模式(COMPACT_PRIO_SYNC_FULL):允许阻塞,允许把脏的文件页回写到存储设备上,并且等回写完成
  • 轻量级同步模式(COMPACT_PRIO_SYNC_LIGHT):允许大多数操作阻塞,但是不允许把脏数据回写到存储设备上;
  • 异步模式(COMPACT_PRIO_ASYNC):不允许阻塞。
  • 成本:完全同步模式>轻量级同步>异步模式

3.3 碎片整理的开始时机

  • 页分配器使用最低水线分屏页失败以后,如果调用者允许直接回收页和写存储设备,并且是最昂贵的分配或者申请不可移动类型的连续页,那么在尝试直接回收页之前,先尝试执行异步模式的内存碎片整理。
  • 页分配器直接回收以后连续分配页仍然失败,如果调用者允许写存储设备,尝试执行轻量级同步模式的内存碎片整理。
  • 每个内存节点有一个页回收线程和一个内存碎片整理线程,页回收线程准备睡眠小段时间的时候,唤醒内存碎片整理线程,内存碎片整理线程执行轻量级同步模式的内存碎片整理。
  • 系统管理员向文件/proc/sys/vm/compact_memory写入任何整数值的时候,在所有内存节点的所有区域上执行完全同步的内存碎片整理。

       内存碎片整理线程名“kcompactd<node_id>”,内存节点的pglist_data的实例成员"kcompactd"指向内存碎片整理线程的进程描述符。

3.4 碎片整理结束条件

        如果迁移扫描器和空闲扫描器相遇,那么内存碎片整理结束。

        如果迁移扫描器和空闲扫描器没有相遇,但是申请或备用的迁移类型至少有一个足够大的空闲页块,那么内存碎片整理结束。

3.5 具体使用方式

1)编译内核时

        如果需要内存碎片整理功能,需要配置CONFIG_COMPACTION

2)命令行下

//设置外部碎片的阈值
root@ubuntu:/home/wy/misc/net# cat /proc/sys/vm/extfrag_threshold
500
//是否允许内部碎片整理移动不可回收的页,1 允许
root@ubuntu:/home/wy/misc/net# cat /proc/sys/vm/compact_unevictable_allowed
1
//写入任何值触发内存碎片整理
root@ubuntu:/home/wy/misc/net# cat /proc/sys/vm/compact_memory 
cat: /proc/sys/vm/compact_memory: Permission denied

参考链接

https://course.0voice.com/v1/course/intro?courseId=2&agentId=0


以上是关于linux内核中内存反碎片技术的主要内容,如果未能解决你的问题,请参考以下文章

Linux 内存池源码浅析

Linux 内存池源码浅析

面试题:Linux是如何避免内存碎片的

原创Linux内存管理 - zoned page frame allocator - 4

Linux内核内存管理架构

嵌入式操作系统的内存,你了解多少?