当前位置: 首页 > news >正文

浅谈Linux内核kswapd的内存域(zone)扫描机制

 

内存域(zone)的基本概念

 

在Linux内核中,物理内存被划分为多个内存域(zone),每个zone管理特定类型的内存区域:

 

ZONE_DMA:用于直接内存访问(DMA)设备的内存区域(0~16MB)

ZONE_DMA32:32位系统DMA可访问内存(0~4GB)

ZONE_NORMAL:常规内存映射区域(x86_64上通常16MB~896MB)

ZONE_HIGHMEM:高端内存区域(仅32位系统,x86_64上不存在)

ZONE_MOVABLE:可移动内存区域(避免内存碎片)

 

kswapd的zone扫描方向原则

 

kswapd按照以下优先级顺序扫描内存域:

 

1.从高水印最低的zone开始扫描

 

 内核计算每个zone的low_wmark_pages(zone)

 

 优先处理内存压力最大的zone

 

2.NUMA节点的本地化优先原则

 

 每个NUMA节点有自己的zone集合

 

 kswapd实例在所属NUMA节点内扫描

 

 通过pgdat->kswapd_classzone_idx跟踪扫描起始点 

 

3.zone类型优先级顺序

 

 扫描顺序遵循:

 

 ZONE_HIGHMEM → ZONE_NORMAL → ZONE_DMA32 → ZONE_DMA

 

 高端内存优先回收(因其易失效),常规内存次之

 

4.水位线驱动(watermark-driven)扫描

 

 当zone->watermark[WMARK_LOW]未被满足时触发回收

 

 回收直到达到zone->watermark[WMARK_HIGH]

 

5.zone_reclaim_mode调节

 

 通过/proc/sys/vm/zone_reclaim_mode控制:

 

 0 (默认):仅回收本地zone

 

 1:启用本地zone强制回收

 

 2:本地回收时写脏页

 

 4:可交换本地内存 

 

底层机制实现(源码级)

 

 关键函数调用链:

 

kswapd()

  → kswapd_try_to_sleep()

    → balance_pgdat(pgdat, order, classzone_idx)

      → for (priority = DEF_PRIORITY; priority >= 0; priority--)

        → sc.priority = priority;

        → for (i = pgdat->kswapd_classzone_idx; i >= 0; i--) {

            struct zone *zone = pgdat->node_zones + i;

            if (!populated_zone(zone)) continue;

            // 扫描当前zone及更低类型zone

            sc.nr_reclaimed += kswapd_shrink_zone(zone, &sc);

          }

    

处理逻辑:

 

 设置初始优先级:DEF_PRIORITY(通常为12)

 

 定位需扫描的classzone_idx:当前NUMA节点中最低水印的zone索引

 

 分层扫描:

 

 外层循环:优先级从高到低(12→0)

 

 内层循环:从classzone_idx向低地址类型zone扫描 

 

 

案例说明:NUMA服务器内存回收

 

环境配置:

 

双路NUMA服务器:Node0(32GB), Node1(32GB)

 

每个节点包含:

ZONE_DMA: 16MB

ZONE_DMA32: 4GB

ZONE_NORMAL: 剩余内存

 

运行内存密集型应用 

 

内存压力场景:

 

 1.Node0的应用占用30GB内存,逼近物理极限

 

 2./proc/zoneinfo显示:

 

 Node 0, zone Normal

     low 5% # watermark_low = 1.6GB

     min 3% # watermark_min = 960MB

     high 8% # watermark_high = 2.56GB

     free: 800MB < low_wmark! 

  

 3.kswapd唤醒与扫描过程:

 

 步骤1:定位压力zone

 

 扫描pg_data_t结构发现Node0的ZONE_NORMAL水印最低

 

 classzone_idx设为ZONE_NORMAL的索引  

 

 步骤2:层级扫描启动

 

 for (i = classzone_idx; i >= 0; i--) { // i=ZONE_NORMAL→ZONE_DMA32→ZONE_DMA

    zone = pgdat->node_zones + i;

    kswapd_shrink_zone(zone, &sc);

 }

 

 先扫描ZONE_NORMAL:回收匿名页和文件页

 

 再扫描ZONE_DMA32:回收可用页面

 

 跳过ZONE_DMA(水印正常)

 

 步骤3:跨zone回收协作

 

 当ZONE_NORMAL回收后空闲内存仍不足时:

 

 if (buffer_heads_over_limit)

    sc.gfp_mask |= __GFP_HIGHMEM; // 尝试回收HIGHMEM

 

 步骤4:NUMA本地性维持

 

 始终在Node0内部回收,即使Node1有大量空闲内存 

 

 4.结果:

 

 成功回收2GB内存后

 

 ZONE_NORMAL空闲达3.6GB > watermark_high

 

 kswapd返回睡眠状态

 

 

特殊场景:ZONE_HIGHMEM回收

 

 

 环境:32位ARM设备(1GB内存)

 

 ZONE_NORMAL: 0-896MB

 

 ZONE_HIGHMEM: 896MB-1024MB

 

 kswapd行为:

 

 1.当ZONE_NORMAL水印告警时:

 

 优先扫描ZONE_HIGHMEM

 

 因HIGHMEM映射开销大,回收可减少TLB压力

 

 2.回收逻辑:

 

 // mm/vmscan.c

    if (buffer_heads_over_limit) {

    sc.gfp_mask |= __GFP_HIGHMEM;

    reclaim_state->reclaimed_slab = 0;

    shrink_slab(...);

    }

 

监控与调优工具 

 

 1.实时观察zone状态:

 

 watch -n 1 "cat /proc/zoneinfo | grep -E 'zone|free|min|low|high'"

 

 2.NUMA内存分布:

 

 numastat -m # 显示各节点内存状态

 

 3.调整zone回收策略:

 

 echo 1 > /proc/sys/vm/zone_reclaim_mode # 启用本地强制回收

 

 总结

 

 kswapd的zone扫描机制是Linux内存管理的核心调度器:

 

 1.压力驱动:优先处理低水印zone

 

 2.层级递进:从HIGHMEM→NORMAL→DMA32→DMA

 

 3.NUMA本地化:限制在所属节点内回收

 

 4.水位闭环:回收至达高水印后停止

 

 5.动态调节:通过zone_reclaim_mode改变策略

 

这种设计确保在复杂内存拓扑下,系统能智能平衡回收效率与性能损耗,是Linux健壮性的关键支撑。

http://www.dtcms.com/a/569990.html

相关文章:

  • 什么是北斗短报文终端?与卫星电话有什么区别?
  • Maven基础(一)
  • MAC-SQL:黄金标准错误
  • 怎样创建基本的网站电子商务网站建设的试卷
  • 网站加盟代理wordpress 本地调试
  • 如何使用AI快速编程实现标注ROS2中sensor_msgs/msg/Image图像色彩webots2025a
  • 专业定制网站开发公司做纺织的用什么网站
  • 20251104让AIO-3576Q38开发板跑Rockchip的原厂Android14进行性能测试【使用天启的DTS】
  • 【案例】三维扫描实现
  • 无人设备遥控器之天线技术分析
  • 宁波市建设工程监理协会网站工程公司年会发言稿
  • 广州旅游团购网站建设中山seo
  • mlir 编译器学习笔记之四 -- 调度
  • 网站建设实施步骤网站源代码上传
  • 2025年 汽车零部件行业MES厂商分析
  • 学校网站制作公司公司企业邮箱怎么填写
  • 网站改版 目的网络建设公司前景
  • Milvus:索引概述(十二)
  • 【25真题】C9之一,质量极高!
  • GitPuk零基础学习,如何进行标签管理
  • Git多分支开发规范与操作指南
  • 国外网站app网址提交大全
  • pulsar SDK在Linux的使用
  • 11.4八股
  • Trae-Agent 使用本地模型
  • 哪个网站开发小程序网站建设与维护的软件
  • Docker(四)_导出容器(不含历史层)
  • GitHub Copilot CLI: How to get started
  • Android ANR的解决方案
  • 亚马逊云科技与OpenAI战略合作深度分析:算力联盟重塑AI产业格局