• 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”,内存节点的pglist_data的实例成员"kcompactd"指向内存碎片整理线程的进程描述符。

    3.4 碎片整理结束条件

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

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

    3.5 具体使用方式

    1)编译内核时

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

    2)命令行下

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

    参考链接

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


  • 相关阅读:
    Spring Cloud框架学习-Spring Cloud Config + Bus 实现配置中心
    解决防火墙导致虚拟机不能ping通宿主机的问题
    安卓JNI使用OpenCV
    Arm功耗管理精讲与实战
    docker配置http proxy代理
    haas506 2.0开发教程-sntp(仅支持2.2以上版本)
    C# List集合赋值
    【C语言趣味教程】(2) 整数类型:数据类型的概念 | 原码反码与补码 | 有符号型和无符类型 | 研究 signed char 与 unsigned char 的取值范围
    【STM32】入门(十):STM32CubeMx下载、安装、使用
    功能上新 | Magic Data Annotator智能出行舱内舱外全场景标注
  • 原文地址:https://blog.csdn.net/WANGYONGZIXUE/article/details/126005158