Linux 內存管理(2):了解內存回收機制

目錄

    • 一、透明大頁
      • 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…