目录

    • 一、透明大页
      • 1.1 原理
      • 1.2 透明大页的三大优势
      • 1.3 透明大页控制接口详解
      • 1.4 使用场景与最佳实践
      • 1.5 问题排查与监控
      • 1.6 与传统大页的对比
    • 二、Linux伙伴系统水位机制详解
      • 2.1 三种核心水位详解
      • 2.2 水位在伙伴系统中的实现
      • 2.3 水位触发机制的实际行为
      • 2.4 水位关键操作接口
      • 2.5 水位优化策略
      • 2.6 水位与其他机制的关系
      • 2.7 kswapd:内存回收守护进程
    • 三、/proc/sys/vm/extfrag_threshold
      • 3.1 基本概念
      • 3.2 作用
      • 3.3 配置方法
      • 3.4 kcompactd:内存碎片规整守护进程
      • 3.5 与伙伴系统水位有什么区别
    • 四、Linux 内存规整机制
      • 4.1 内存规整关键特性演进
      • 4.2 新旧内核性能对比分析
      • 4.3 kswapd与kcompactd的协同机制
      • 4.4 诊断命令与参数调整
    • 五、/proc/sys/vm/min_free_kbytes
      • 5.1 这个保留的内存能不能被使用?
      • 5.2 保留的意义是什么?
      • 5.3 详细解释和工作机制
      • 5.4 假如设置 `echo 16384 > /proc/sys/vm/min_free_kbytes`
    • 六、直接同步回收(Direct Reclaim)深度解析
      • 6.1 直接同步回收 vs kswapd/kcompactd
      • 6.2 直接同步回收的完整执行流程
      • 6.3 性能影响与优化
      • 6.4 总结

一、透明大页

# 1. 手动触发内存压缩
echo 1 > /proc/sys/vm/compact_memory# 2. 检查碎片指数
cat /proc/buddyinfo
cat /proc/pagetypeinfo# 3. 调整透明大页
echo always > /sys/kernel/mm/transparent_hugepage/enabled

1.1 原理

  透明大页(Transparent HugePages,简称 THP)是 Linux 内核的一种自动化内存优化技术,它通过将多个标准 4KB 页动态合并为更大的 2MB 或 1GB 页,显著提升系统性能。/sys/kernel/mm/transparent_hugepage/enabled 正是控制这一特性的关键接口。

特性标准页 (4KB)透明大页 (2MB/1GB)
页大小4KB2MB (512倍) 或 1GB
页表项数量多 (约 50 万/GB)少 (512/GB)
TLB 覆盖率
内存管理静态分配动态合并
请求内存
成功
应用程序
内核
启用 THP?
尝试分配 2MB 大页
连续 2MB 可用?
直接分配大页
分配 4KB 小页
后台 khugepaged 合并
替换为大页
始终分配 4KB 小页

  在 Linux 系统中,可以通过以下几种方法来确认内核是否开启透明大页(Transparent Huge Pages,THP)功能:

方法一:查看 /sys/kernel/mm/transparent_hugepage/enabled 文件

  透明大页的状态信息存储在 /sys/kernel/mm/transparent_hugepage/enabled 文件中,你可以使用 cat 命令查看该文件的内容:

cat /sys/kernel/mm/transparent_hugepage/enabled
  • 输出示例及含义
    • 如果输出为 [always] madvise never,表示透明大页功能已开启,并且始终尝试使用大页。方括号 [] 括起来的选项表示当前生效的设置。
    • 如果输出为 always madvise [never],则表示透明大页功能已关闭。
    • 如果输出为 always [madvise] never,表示使用 madvise 系统调用的方式来决定是否使用大页,即应用程序可以通过 madvise 系统调用显式地请求或避免使用大页。

方法二:使用 grep 结合 /proc/meminfo 文件
  你也可以通过在 /proc/meminfo 文件中查找与透明大页相关的信息来间接确认其状态:

grep -i huge /proc/meminfo
  • 输出示例及含义
    • 如果输出中包含类似 AnonHugePages 的信息,且其值不为 0,则说明透明大页功能可能是开启的,因为 AnonHugePages 表示匿名大页的使用情况。例如:
AnonHugePages:    204800 kB

   不过这种方法只能作为一个参考,因为即使 AnonHugePages 为 0,也不能完全确定透明大页功能是关闭的,还需要结合前面的方法来综合判断。

1.2 透明大页的三大优势

  1. TLB(转换后援缓冲器)优化
  • 问题:TLB 容量有限(通常 64-512 条目)
  • 解决:单个 2MB 页表项覆盖 512 倍内存区域
  • 效果:TLB 未命中率降低 80-90%
  1. 页表遍历加速
  • 传统页表:4 级页表查找(PGD→PUD→PMD→PTE)
  • 大页页表:跳过 PTE 层查找(PGD→PUD→PMD)
  • 性能提升:内存访问延迟降低 30-70%
  1. 内存操作效率
操作标准页 (512次)大页 (1次)提升倍数
页分配/释放512 次系统调用1 次512x
缺页中断512 次1 次512x
内存清零512 次1 次512x

1.3 透明大页控制接口详解

核心控制文件

/sys/kernel/mm/transparent_hugepage/enabled
  • 可选值
    • always:强制所有内存使用大页
    • madvise:仅对标记区域使用(推荐)
    • never:完全禁用

相关调优参数

文件路径功能推荐值
/defrag碎片整理策略defer (延迟整理)
/khugepaged/defrag后台整理1 (启用)
/hpage_pmd_size大页尺寸2097152 (2MB)

1.4 使用场景与最佳实践

推荐启用场景

  • 内存密集型应用:MySQL, MongoDB, Redis
  • 科学计算:MATLAB, TensorFlow
  • 虚拟化平台:KVM, Docker
  • 大数据处理:Spark, Hadoop

配置示例

# 启用透明大页(madvise模式)
echo madvise > /sys/kernel/mm/transparent_hugepage/enabled# 优化后台合并进程
echo 1 > /sys/kernel/mm/transparent_hugepage/khugepaged/defrag
echo 10 > /sys/kernel/mm/transparent_hugepage/khugepaged/pages_to_scan# 应用程序主动请求大页
#include <sys/mman.h>
posix_memalign(&ptr, 2*1024*1024, size);
madvise(ptr, size, MADV_HUGEPAGE);

禁用场景

  • 实时系统:避免合并导致的延迟波动
  • 内存碎片严重:物理内存不足时
  • 特定数据库:如 Oracle 推荐禁用

1.5 问题排查与监控

# 查看大页使用情况
grep AnonHugePages /proc/meminfo# 监控khugepaged活动
grep -E 'thp|khugepaged' /proc/vmstat# ubuntu可视化工具
sudo apt install hugeadm
hugeadm --pool-list

问题: 内存碎片导致大页分配失败
解决方案:

# 手动触发碎片整理
echo 1 > /proc/sys/vm/compact_memory# 调整碎片阈值
sysctl vm.extfrag_threshold=500

问题: khugepaged 占用高 CPU
解决方案:

# 减少扫描频率
echo 100 > /sys/kernel/mm/transparent_hugepage/khugepaged/scan_sleep_millisecs

1.6 与传统大页的对比

特性透明大页 (THP)传统大页 (HugeTLB)
配置方式自动/动态静态预分配
管理复杂度低 (内核自动管理)高 (手动配置)
内存利用率高 (按需分配)低 (固定预留)
适用场景通用工作负载特定应用
调整灵活性运行时动态调整需重启生效

最佳实践:现代系统优先使用 THP,仅在特殊需求(如 DPDK)时使用传统大页。

  透明大页技术通过智能化地平衡内存效率与系统开销,已成为现代 Linux 系统性能优化的关键组件。合理配置后,可使内存密集型应用获得高达 50% 的性能提升,同时保持系统的灵活性和稳定性。

二、Linux伙伴系统水位机制详解

  伙伴系统中的水位(Watermarks) 是Linux内核内存管理的关键机制,用于动态监控内存压力触发内存回收操作。它定义了系统内存使用的临界阈值,确保内存分配不会耗尽系统资源。

内存充足
内存压力
内存紧张
内存区域
最高水位 high_wmark
低水位 low_wmark
最低水位 min_wmark
正常分配
唤醒kswapd
直接回收

2.1 三种核心水位详解

最高水位 (high_wmark)

  • 位置:内存区域的顶部
  • 含义:系统内存充足状态
  • 触发行为
    • 允许快速内存分配
    • kswapd休眠状态
  • 计算公式
    high_wmark = min_free_kbytes * 5 / 4
    

低水位 (low_wmark)

  • 位置:high和min之间
  • 含义:中等内存压力
  • 触发行为
    • 唤醒kswapd守护进程
    • 开始后台页面回收
  • 视觉表现
    内存使用 [||||||||||__________] low_wmark
    

最低水位 (min_wmark)

  • 位置:内存区域的底部
  • 含义:严重内存压力
  • 触发行为
    • 直接同步回收(阻塞分配进程)
    • 可能触发OOM Killer
  • 计算公式
    min_free_kbytes = sqrt(总内存*16) // 内核自动计算
    也可以人为设定数值
    

2.2 水位在伙伴系统中的实现

数据结构

struct zone {unsigned long watermark[NR_WMARK]; // 三水位值// [0] = min_wmark// [1] = low_wmark// [2] = high_wmarkstruct per_cpu_pageset pageset[NR_CPUS];struct free_area free_area[MAX_ORDER]; // 伙伴系统核心
}

内存分配检查流程

static struct page *get_page_from_freelist(...) {for_each_zone(zone) {// 检查当前区域是否低于水位if (!zone_watermark_ok(zone, order, mark, ...))continue;// 尝试分配页面page = buffered_rmqueue(zone, order, gfp_mask);if (page)return page;}return NULL;
}

2.3 水位触发机制的实际行为

正常状态(高于high_wmark)

App伙伴系统分配请求立即分配App伙伴系统

中等压力(低于low_wmark)

App伙伴系统kswapd页面缓存分配请求唤醒后台回收回收页面返还页面延迟分配App伙伴系统kswapd页面缓存

严重压力(低于min_wmark)

App伙伴系统直接回收分配请求阻塞进程同步回收内存回收完成分配内存App伙伴系统直接回收

2.4 水位关键操作接口

查看当前水位

# 查看所有内存区域水位
cat /proc/zoneinfo | grep -E 'Node|min|low|high'# 示例输出
Node 0, zone   Normalpages free     32415min      14895low      18618high     22341

调整水位参数

# 临时调整
echo 65536 > /proc/sys/vm/min_free_kbytes

监控水位变化

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

2.5 水位优化策略

嵌入式设备优化

# 减少保留内存(内存紧张设备)
echo 8192 > /proc/sys/vm/min_free_kbytes# 更积极回收
echo 150 > /proc/sys/vm/vfs_cache_pressure

解决常见问题:频繁触发直接回收导致卡顿

# 查看事件计数
grep "pgsteal" /proc/vmstat# 优化方案:
1. 增加 min_free_kbytes
2. 优化应用程序内存使用
3. 添加物理内存

2.6 水位与其他机制的关系

伙伴系统水位
触发kswapd
触发直接回收
页面缓存回收
SLAB收缩
进程阻塞
OOM Killer
文件系统操作加速
内核对象分配加速

  水位机制是Linux内存管理的"预警系统",它:

  1. 预防内存耗尽:提前触发回收避免OOM
  2. 平衡性能:后台回收减少阻塞
  3. 动态适应:根据系统负载自动调整压力响应

  理解水位机制对优化系统性能、诊断内存压力问题至关重要,特别是在高负载服务器和资源受限的嵌入式系统中。

2.7 kswapd:内存回收守护进程

核心功能

  • 内存水位维护:当系统空闲内存低于低水位线(low watermark)时,kswapd被唤醒,异步回收内存,确保空闲内存恢复到高水位线(high watermark)以上。

  • 回收对象:主要回收两类内存:

    • 文件页(Page Cache):缓存的文件数据,可直接丢弃(除非脏页需写回磁盘)。
    • 匿名页(Anonymous Pages):进程堆栈等数据,需交换(swap)到磁盘。
  • 触发条件

    • 常规周期唤醒(默认100毫秒)。
    • 进程分配内存失败时(如alloc_pages()慢路径触发wakeup_kswapd())。
      在这里插入图片描述
  • 异步操作:不阻塞进程,后台运行。

  • 优先级策略:按页面活跃度(Active/Inactive LRU)选择回收对象。

  • NUMA优化:每个NUMA节点独立运行一个kswapd线程(如kswapd0kswapd1)。


三、/proc/sys/vm/extfrag_threshold

3.1 基本概念

  extfrag_threshold 是Linux 内核中一个与内存碎片管理相关的参数,是一个范围在 0 到 1000 的整数,它主要用于衡量系统对外部内存碎片的容忍程度。外部内存碎片指的是由于频繁的内存分配和释放操作,导致物理内存中出现大量不连续的空闲内存块,使得即使系统中总的空闲内存量充足,但无法分配出连续的大块内存的现象。

3.2 作用

  这个参数在内核进行内存分配决策时发挥着重要作用。内核在分配内存时,会根据当前系统的内存碎片情况和 extfrag_threshold 的值来选择合适的分配策略:

  • 低阈值(接近 0):表示系统对内存碎片的容忍度较低。当内存碎片程度达到较低水平时,内核就会采取积极的措施来减少碎片,例如进行内存紧凑(memory compaction)操作,将分散的空闲内存块移动到一起,形成连续的大块空闲内存,以满足后续的大内存分配请求。不过,内存紧凑操作会消耗一定的系统资源和时间,可能会对系统性能产生一定影响。
  • 高阈值(接近 1000):意味着系统对内存碎片有较高的容忍度。只有当内存碎片程度非常严重时,内核才会尝试进行内存紧凑或其他减少碎片的操作。在这种情况下,系统在一定程度上可以避免频繁进行内存紧凑带来的性能开销,但可能会面临无法分配大块连续内存的风险。

3.3 配置方法

  可以通过 /proc/sys/vm/extfrag_threshold 文件来查看和修改 extfrag_threshold 的值。

  • 查看当前值:使用以下命令可以查看当前系统中 extfrag_threshold 的设置:
cat /proc/sys/vm/extfrag_threshold
  • 修改值:可以使用 echo 命令将新的值写入该文件来修改参数设置。例如,将 extfrag_threshold 设置为 500:
echo 500 > /proc/sys/vm/extfrag_threshold

  合理设置 extfrag_threshold 参数对于平衡系统对内存碎片的处理和系统性能非常重要。在实际应用中,需要根据系统的具体负载和内存使用情况进行调整。

3.4 kcompactd:内存碎片规整守护进程

核心功能

  • 碎片合并:将零散小内存块合并为高阶连续块(如将order=0的4KB页合并为order=2的16KB页),满足大块内存请求(如DMA、透明大页)。
  • 迁移策略:扫描内存区域,将可移动页(MIGRATE_MOVABLE)从低地址向高地址迁移,形成连续空闲空间。

触发条件

  • 被动触发:高阶内存分配失败时(如alloc_pages(order>0)失败)。
  • 主动触发:内核≥5.0支持主动规整(Proactive Compaction),预测碎片风险提前规整。

工作流程

// 简化版规整逻辑(mm/compaction.c)
compact_zone() {isolate_migratepages();  // 隔离可移动页migrate_pages();         // 迁移至空闲区域release_freepages();     // 释放新连续块
}

3.5 与伙伴系统水位有什么区别

  • 功能用途不同
    • extfrag_threshold 关注的是内存碎片的程度,目的是在内存碎片达到一定水平时维护内存的连续性,以确保能够分配出连续的大块内存。
    • 伙伴系统的水位关注的是内存的使用量,目的是在内存分配时发现内存资源紧张回收内存,保证系统有足够的可用内存。
  • 数值范围和含义不同
    • extfrag_threshold 是一个 0 到 1000 的整数,数值越大表示系统对内存碎片的容忍度越高。
    • 伙伴系统的水位是以物理页框的数量来表示的,不同的内存区域(如 DMA 区、普通区等)可能有不同的水位值,这些值反映了该区域内存的使用状态。
  • 两者的联系
      虽然 extfrag_threshold 和伙伴系统的水位是不同的概念,但它们都会影响内核的内存管理决策。例如,当系统内存接近或低于伙伴系统的低水位,同时内存碎片程度达到 extfrag_threshold 设定的阈值时,内核可能会更积极地进行内存紧凑和回收操作,以满足内存分配需求并减少碎片。

四、Linux 内存规整机制

4.1 内存规整关键特性演进

特性内核版本支持嵌入式系统配置方式功能描述
异步/后台规整<4.6:不支持
≥4.6:支持
echo 1 > /sys/kernel/mm/transparent_hugepage/khugepaged/defragkcompactd 后台线程自动规整
主动规整(Proactive)<5.2:不支持
≥5.2:默认开启
echo 1 > /sys/kernel/mm/transparent_hugepage/defrag预测性内存规整避免碎片
手动触发< 3.10:不支持
≥3.10:支持
echo 1 > /proc/sys/vm/compact_memory立即触发全系统内存规整
碎片阈值<4.12:不支持
≥4.12:支持
echo 500 > /proc/sys/vm/extfrag_threshold碎片敏感度调节(0-1000)
规整力度<5.15:不支持
≥5.15:支持
echo 20 > /proc/sys/vm/compaction_proactiveness规整激进程度(0-100)
# 减少 kcompactd CPU 占用 (嵌入式设备关键)
echo 1000 > /sys/kernel/mm/transparent_hugepage/khugepaged/scan_sleep_millisecs# 限制每次扫描页数
echo 256 > /sys/kernel/mm/transparent_hugepage/khugepaged/pages_to_scan

4.2 新旧内核性能对比分析

在这里插入图片描述
根本原因解析

  1. kcompactd 作用(≥4.6):

    • 持续后台内存碎片整理
    • 预防性合并可移动页
    • 保障高阶连续内存可用
  2. 主动规整优势(≥5.2)

4.3 kswapd与kcompactd的协同机制

协作场景

  1. 内存分配失败时
    • 先唤醒kswapd回收内存 → 若仍失败,触发kcompactd规整碎片。
  2. 后台维护
    • kswapd回收后若碎片指数高(/proc/buddyinfo显示高阶块稀缺),唤醒kcompactd

性能影响对比

指标kswapdkcompactd
CPU开销中(扫描LRU/写swap)高(页面迁移消耗大量CPU)
延迟低(异步)可能阻塞进程(同步迁移)
主要目标释放空闲页提升连续内存可用性

总结

  • kswapd:内存“回收者”,专注维护水位,异步释放内存。
  • kcompactd:碎片“修复师”,合并零散页,保障大块内存分配。
  • 协作价值
      二者形成“释放+规整”闭环,从空间(回收碎片)和时间(异步操作)维度优化内存管理。尤其在≥5.2内核中,主动规整机制显著提升长期运行稳定性,避免旧版本因碎片累积导致的OOM问题。

4.4 诊断命令与参数调整

监控命令

  • 碎片指数
    cat /proc/buddyinfo  # 各阶空闲块分布(阶数越高越连续)
    cat /proc/vmstat | grep compact  # 规整次数统计
    
  • 回收压力
    cat /proc/zoneinfo | grep -E 'Node|min|low|high'  # 水位线
    cat /proc/vmstat | grep kswapd  # 回收页面计数
    

调优参数

目标操作文件路径
降低kswapd频率延长扫描间隔/sys/kernel/mm/transparent_hugepage/khugepaged/scan_sleep_millisecs
减少规整开销限制每次扫描页数/sys/kernel/mm/transparent_hugepage/khugepaged/pages_to_scan
调整碎片敏感度增大阈值(>500减少规整)echo 800 > /proc/sys/vm/extfrag_threshold
关闭透明大页避免频繁高阶分配内核启动参数加transparent_hugepage=never

嵌入式场景特别注意事项

  1. 资源受限
    • 减少kcompactd扫描页数(pages_to_scan),避免CPU过载。
  2. 无swap设备
    • kswapd仅回收文件页,匿名页回收失效,需依赖OOM KillerLMKD
  3. 实时性要求
    • 禁用主动规整(compaction_proactiveness=0),减少非确定性延迟。

五、/proc/sys/vm/min_free_kbytes

5.1 这个保留的内存能不能被使用?

  在系统内存充足时:可以! 当系统的空闲内存 (free) 远大于 min_free_kbytes 时,这部分“保留”的内存区域完全可以被用户进程申请和使用。它并不是被永久锁定或隔离的区域。

  在系统内存紧张时:不行! 当系统的空闲内存接近或低于 min_free_kbytes 设定的阈值时,内核会强烈阻止用户进程再消耗掉这最后一点“保留”内存。内核会采取激进措施(直接回收、OOM Killer)来释放内存,确保空闲内存恢复到 min_free_kbytes 之上。

5.2 保留的意义是什么?

保留这部分内存的核心目的是保障系统在最极端内存压力下的基本功能性和稳定性,避免系统完全崩溃。具体来说:

  • 防止死锁和系统僵死: 这是最主要的原因。当所有物理内存都被耗尽时,内核自身执行关键操作(如调度进程、处理中断、执行 I/O、回收内存)都可能需要分配少量内存。如果连这点内存都没有,系统会陷入死锁状态:需要内存来释放内存,但已无内存可用,整个系统完全无响应(僵死)。min_free_kbytes 确保在最坏情况下,内核仍有“救命钱”来执行这些关键操作
  • 支持内核关键操作:
    • 处理硬件中断: 中断处理程序可能需要分配内存缓冲区。
    • 网络和存储 I/O: 网络数据包和磁盘块读写在进入用户空间前需要内核缓冲区。
    • 进程创建/销毁: 创建新进程(fork/exec)需要分配内核数据结构。
    • 页面回收: kswapd 或直接回收在执行时需要内存来管理回收过程本身(例如,存放需要写回的脏页链表)。
  • 维持 kswapd 有效工作: kswapd 是内核的后台内存回收守护进程。当空闲内存低于 low 水位线(与 min_free_kbytes 相关)时,kswapd 会被唤醒并开始后台异步回收内存。如果允许空闲内存降到极低甚至为零,kswapd 可能来不及回收,迫使进程在申请内存时进行代价高昂的直接回收,导致严重的延迟(卡顿)。保留内存给 kswapd 一定的缓冲空间和时间来工作。
  • 避免过早触发 OOM Killer: OOM Killer 是内核在内存完全耗尽、回收失败后的最后手段,它会强制杀死进程来释放内存。这个过程非常粗暴,可能导致重要服务中断。保留内存为内存回收提供了缓冲,降低了过早触发 OOM Killer 的概率。

5.3 详细解释和工作机制

  1. 水位线: 内核基于 min_free_kbytes 计算出三个关键的内存水位线:

    • min: 直接对应于 min_free_kbytes。这是最后的防线,空闲内存绝对不能低于此值。
    • low: 高于 min。当空闲内存低于 low 时,内核唤醒 kswapd 开始后台异步回收内存。
    • high: 高于 low。当空闲内存回升到 high 时,kswapd 停止回收。
  2. 内存分配行为:

    • 当用户进程通过 malloc 等申请内存时,最终会触发内核的页面分配器(如 buddy allocator)分配物理页框。
    • 分配器会检查当前空闲内存是否充足。
      • 如果空闲内存 > low:分配成功,进程继续运行。
      • 如果空闲内存 < low 但 > min:分配器可能会让进程进入等待状态,同时唤醒或加速 kswapd 进行回收。回收出足够内存后,进程被唤醒并获得内存。
      • 如果空闲内存 <= min:分配器会进入直接回收模式。这发生在申请内存的进程上下文中,是同步阻塞的。该进程会被阻塞,内核在其上下文中立即尝试回收内存(可能非常慢)。如果直接回收失败且内存仍低于 min,内核最终会调用 OOM Killer 选择并杀死一个或多个进程来释放内存。在这个阶段,分配器会拒绝分配任何可能使空闲内存进一步低于 min 的请求,严格保护这块保留内存。

5.4 假如设置 echo 16384 > /proc/sys/vm/min_free_kbytes

  • 这确实将最低保留内存设置为 16MB (16384 KB)。
  • 将默认值(通常为几MB)翻倍意味着:
    • 好处: 系统在内存压力下有更大的缓冲空间,kswapd 有更多时间工作,直接回收和 OOM Killer 被触发的可能性降低,系统在高压下可能更稳定。
    • 潜在代价: 稍微增加了“浪费”内存的可能性。在内存非常紧张的系统中,16MB 可能意味着一个额外的进程无法运行(因为内核要保护这 16MB)。更关键的是,如果设置过高(比如在总内存很小的系统上设得太大),可能导致 kswapd 过度活跃,即使系统负载不高也频繁回收内存,反而增加 CPU 开销和降低性能(回收本身有成本)。它也可能过早触发直接回收,因为 low 水位线也相应提高了。

  min_free_kbytes 设置的内存是动态保留的底线。在内存充足时,它可被自由使用;在内存紧张时,它是内核维持自身运转和避免灾难性崩溃的最后保障。你将其设置为 16MB 增加了安全缓冲,但需注意过高设置可能带来性能开销。最佳值取决于你的系统总内存大小和工作负载特性。监控 /proc/vmstat (关注 pgscan_kswapd, pgscan_direct, oom_kill 等) 和 /proc/meminfo 可以帮助评估当前设置是否合理。

六、直接同步回收(Direct Reclaim)深度解析

  当系统内存低于最低水位(min_wmark)时触发的直接同步回收是Linux内核最紧急的内存回收机制,其执行过程与kswapd/kcompactd有本质区别。

6.1 直接同步回收 vs kswapd/kcompactd

特性直接同步回收kswapdkcompactd
触发条件内存≤min_wmark内存≤low_wmark碎片指数超标
执行者请求内存的进程自身内核后台线程内核后台线程
执行模式同步阻塞异步异步
优先级最高(可抢占其他进程)普通普通
延迟影响直接导致进程卡顿无感知可能轻微影响

6.2 直接同步回收的完整执行流程

应用程序内存管理子系统文件系统交换分区内存分配请求检查空闲内存 < min_wmark?阻塞进程!同步回收页面缓存刷写脏页到磁盘返回干净页同步交换匿名页压缩/写入swap释放物理页解除阻塞,分配内存应用程序内存管理子系统文件系统交换分区

具体步骤解析:

  1. 进程阻塞

    • alloc_pages()检测到zone_watermark_ok() == false
    • 当前进程进入TASK_UNINTERRUPTIBLE状态
  2. 页面缓存回收

    // 内核源码 mm/vmscan.c
    unsigned long shrink_page_list(...) {while (!list_empty(page_list)) {if (PageDirty(page)) {// 同步写回磁盘pageout(page, mapping); } else {// 直接回收干净页__remove_mapping(...);}}
    }
    
  3. 匿名页交换

    • 对非活动匿名页执行:
      swap_writepage(page, &wbc);  // 同步写swap
      
    • 若配置了zswap,优先压缩到内存
  4. SLAB缓存收缩

    shrink_slab(GFP_KERNEL, ...);  // 回收dentries/inodes
    
  5. 解除阻塞

    • 当释放足够页面后,唤醒进程继续分配内存
    • 若回收失败,触发OOM Killer

6.3 性能影响与优化

性能瓶颈分析

直接同步回收
磁盘I/O阻塞
高CPU占用
进程延迟
应用卡顿
系统负载飙升
请求超时

优化策略(嵌入式场景)

  1. 预防性调优

    # 增加保留内存缓冲
    echo 16384 > /proc/sys/vm/min_free_kbytes  # 默认值的2倍# 降低交换倾向
    echo 10 > /proc/sys/vm/swappiness
    
  2. 减少回收压力

    // 代码层面:避免突发内存分配
    for (i=0; i<1000; i++) {// 错误:每次分配4KBbuffer = malloc(4096); // 正确:批量分配40KBif (i % 10 == 0) big_buf = malloc(40960);
    }
    
  3. 监控诊断工具

    # 追踪直接回收事件
    echo 'vfs:shrink_*' > /sys/kernel/debug/tracing/set_event
    cat /sys/kernel/debug/tracing/trace_pipe# 输出示例
    kworker/0:1-125   [000] ....   316.256367: mm_vmscan_direct_reclaim_begin: order=0
    kworker/0:1-125   [000] ....   316.259412: mm_vmscan_direct_reclaim_end: nr_reclaimed=32
    

6.4 总结

虽然直接回收由进程自身执行,但会与kswapd互动:

kswapd正在运行
kswapd未运行
直接回收开始
检查kswapd状态
等待kswapd部分结果
完整执行回收
若回收困难 唤醒kswapd协助

直接同步回收是Linux内存管理的"紧急制动"机制:

  1. 同步执行:由请求进程直接执行,导致阻塞
  2. 代价高昂:涉及磁盘I/O和密集计算
  3. 触发条件:内存≤min_wmark的危急状态
  4. 优化核心
    • 增加min_free_kbytes缓冲
    • 避免内存分配尖峰
    • 监控direct reclaim事件

在嵌入式系统中,通过合理配置保留内存和优化应用行为,可显著降低直接回收发生概率,保障系统实时性。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/pingmian/89561.shtml
繁体地址,请注明出处:http://hk.pswp.cn/pingmian/89561.shtml
英文地址,请注明出处:http://en.pswp.cn/pingmian/89561.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

前端学习7:CSS过渡与动画--补间动画 (Transition) vs 关键帧动画 (Animation)

一、补间动画&#xff08;Tween Animation&#xff09;vs 关键帧动画&#xff08;Keyframe Animation&#xff09;概念对比表&#xff1a;补间动画 (Transition)关键帧动画 (Animation)定义元素从初始状态到结束状态的过渡效果通过定义多个关键帧控制动画的中间状态触发方式需要…

PyTorch 损失函数详解:从理论到实践

目录 一、损失函数的基本概念 二、常用损失函数及实现 1. 均方误差损失&#xff08;MSELoss&#xff09; 2. 平均绝对误差损失&#xff08;L1Loss/MAELoss&#xff09; 3. 交叉熵损失&#xff08;CrossEntropyLoss&#xff09; 4. 二元交叉熵损失&#xff08;BCELoss&…

MinIO深度解析:从核心特性到Spring Boot实战集成

在当今数据爆炸的时代&#xff0c;海量非结构化数据的存储与管理成为企业级应用的关键挑战。传统文件系统在TB级数据面前捉襟见肘&#xff0c;而昂贵的云存储服务又让中小企业望而却步。MinIO作为一款开源高性能对象存储解决方案&#xff0c;正以其独特的技术优势成为开发者的首…

腾讯云服务上下载docker以及使用Rabbitmq的流程

执行以下命令&#xff0c;添加 Docker 软件源并配置为腾讯云源。sudo yum-config-manager --add-repohttps://mirrors.cloud.tencent.com/docker-ce/linux/centos/docker-ce.repo sudo sed -i "s/download.docker.com/mirrors.tencentyun.com\/docker-ce/g" /etc/yu…

UE5 一些关于过场动画sequencer,轨道track的一些Python操作

删除多余的轨道 import unreal def execute():movie_scene_actors []sequence_assets []data 0.0# 获取编辑器实用工具库lib unreal.EditorUtilityLibrary()selected_assets lib.get_selected_assets()for asset in selected_assets:if asset.get_class() unreal.LevelS…

前端性能优化“核武器”:新一代图片格式(AVIF/WebP)与自动化优化流程实战

前端性能优化“核武器”&#xff1a;新一代图片格式(AVIF/WebP)与自动化优化流程实战 当你的页面加载时间超过3秒时&#xff0c;用户的跳出率会飙升到40%以上。而在所有的前端性能优化手段中&#xff0c;图片优化无疑是投入产出比最高的一环。一张未经优化的巨大图片&#xff0…

单元测试学习+AI辅助单测

标题单元测试衡量指标具体测试1、Resource2、MockBean3、Test4、Test模板5、单测示例H2数据库JSON1、使用方式AI辅助单测使用方法单元测试 单元测试一般指程序员在写好代码后&#xff0c;提交测试前&#xff0c;需要验证自己的代码是否可以正常工作&#xff0c;同时将自己的代…

Spring Cloud Gateway与Envoy Sidecar在微服务请求路由中的架构设计分享

Spring Cloud Gateway与Envoy Sidecar在微服务请求路由中的架构设计分享 在现代微服务架构中&#xff0c;请求路由层承担着流量分发、安全鉴权、流量控制等多重职责。传统的单一网关方案往往面临可扩展性和可维护性挑战。本文将从真实生产环境出发&#xff0c;分享如何结合Spri…

GitHub Pages+Jekyll 静态网站搭建(二)

GitHub PagesJekyll 静态网站搭建&#xff08;二&#xff09;GitHub PagesJekyll 静态网站搭建&#xff08;二内容简介搭建模板网站部署工作流程GitHub PagesJekyll 静态网站搭建&#xff08;二 内容简介 &#x1f6a9; Tech Contents 该文主要涉及Jekyll主题的下载与使用。Gi…

Django 实战:I18N 国际化与本地化配置、翻译与切换一步到位

文章目录一、国际化与本地化介绍定义相关概念二、安装配置安装 gettext配置 settings.py三、使用国际化视图中使用序列化器和模型中使用四、本地化操作创建或更新消息文件消息文件说明编译消息文件五、项目实战一、国际化与本地化介绍 定义 国际化和本地化的目标&#xff0c;…

通过国内扣子(Coze)搭建智能体并接入discord机器人

国内的扣子是无法直接授权给discord的&#xff0c;但是用国外的coze的话&#xff0c;大模型调用太贵&#xff0c;如果想要接入国外的平台&#xff0c;那就需要通过调用API来实现。 1.搭建智能体&#xff08;以工作流模式为例&#xff09; 首先&#xff0c;我们需要在扣子平台…

【办公类-107-02】20250719视频MP4转gif(削减MB)

背景需求 最近在写第五届智慧项目结题(一共3篇)写的昏天黑地,日以继夜。 我自己《基于“AI技术”的幼儿园教学资源开发和运用》提到了AI绘画、AI视频和AI编程。 为了更好的展示AI编程的状态,我在WORD里面插入了MP4转gif的动图。 【教学类-75-04】20241023世界名画-《蒙…

一文讲清楚React的render优化,包括shouldComponentUpdate、PureComponent和memo

文章目录一文讲清楚React的render优化&#xff0c;包括shouldComponentUpdate、PureComponent和memo1. React的渲染render机制2. shouldComponentUpdate2.1 先上单组件渲染&#xff0c;验证state变化2.2 上父子组件&#xff0c;验证props2. PureComponent2.1 单组件验证state2.…

物联网iot、mqtt协议与华为云平台的综合实践(万字0基础保姆级教程)

本学期的物联网技术与应用课程&#xff0c;其结课设计内容包含&#xff1a;mqtt、华为云、PyQT5和MySQL等结合使用&#xff0c;完成了从华为云配置产品信息以及转发规则&#xff0c;到mqtt命令转发&#xff0c;再到python编写逻辑代码实现相关功能&#xff0c;最后用PyQT5实现面…

使用IntelliJ IDEA和Maven搭建SpringBoot集成Fastjson项目

使用IntelliJ IDEA和Maven搭建SpringBoot集成Fastjson项目 下面我将详细介绍如何在IntelliJ IDEA中使用Maven搭建一个集成Fastjson的SpringBoot项目&#xff0c;包含完整的环境配置和代码实现。 一、环境准备 软件要求 IntelliJ IDEA 2021.x或更高版本JDK 1.8或更高版本&#x…

Java从入门到精通!第九天, 重点!(集合(一))

十一、集合1. 为什么要使用集合(1) 数组存在的弊端1) 数组在初始化之后&#xff0c;长度就不能改变&#xff0c;不方便扩展。2) 数组中提供的属性和方法比较少&#xff0c;不便于进行添加、删除、修改等操作&#xff0c;并且效率不高&#xff0c;同时无法直接存储元素的个数。3…

为什么使用时序数据库

为什么使用时序数据库&#xff1f; 时序数据库&#xff08;Time-Series Database, TSDB&#xff09;是专为时间序列数据优化的数据库&#xff0c;相比传统关系型数据库&#xff08;如MySQL&#xff09;或NoSQL数据库&#xff08;如MongoDB&#xff09;&#xff0c;它在以下方面…

计算机网络:(十一)多协议标记交换 MPLS

计算机网络&#xff1a;&#xff08;十一&#xff09;多协议标记交换 MPLS前言一、传统网络的问题二、MPLS&#xff1a;给数据包贴个“标签”三、MPLS的工作流程1. 入站2. 中间3. 出站四、MPLS的能力前言 前面我们讲解了计算机网络中网络层的相关知识&#xff0c;包括网络层转发…

docker run elasticsearch 报错

谷粒商城 p103 前提条件&#xff1a; 下载镜像文件 #存储和检索数据 docker pull elasticsearch:7.4.2 #可视化检索数据 docker pull kibana:7.4.2 创建挂载的文件和配置 mkdir -p /mydata/elasticsearch/config mkdir -p /mydata/elasticsearch/data echo "http.h…

巧用Callbre RVE生成DRC HTML report及CTO的使用方法

对于后端版图人员&#xff0c;在芯片TO前的LV signoff阶段&#xff0c;犹如一段漫长而有期待的朝圣之旅&#xff0c;需要耐心&#xff0c;毅力和信心&#xff0c;在庞杂的DRC中找到一条收敛之路。为了让此路更为清晰收敛&#xff0c;Calibre提供了一套可追溯对比的富文本方式-H…