全部產品
Search
文件中心

Alibaba Cloud Linux:THP reclaim功能

更新時間:Jul 17, 2024

THP(Transparent Huge Page)reclaim功能用於解決因透明大頁THP帶來的記憶體問題(例如OOM)。本文介紹實現THP reclaim功能的介面,以及介面的樣本操作說明。

背景資訊

Linux作業系統的記憶體採用分頁管理員模式,其中的THP是指核心中2 MiB或1 GiB大小的大頁面(普通的小頁面大小為4 KiB),一般被稱為透明大頁。基於應用程式使用到的記憶體範圍越來越大,地址轉換產生的開銷變得不可忽視。因此,當伺服器上的應用程式申請記憶體時,核心會根據進程的實際情況動態分配透明大頁,透明大頁可以減少TLB(Translation Lookaside Buffer) Miss的出現機率,從而提升應用程式的效能。

THP在帶來效能提升的同時,也產生了一定副作用,即可能產生Memory bloating(記憶體膨脹)問題。該問題產生的原因說明:透明大頁申請釋放的粒度為2 MiB(即512個小頁面),相較於小頁面,透明大頁更容易產生記憶體片段,進而導致核心分配的記憶體容量大於實際需要的記憶體容量。

Memory bloating可能引發OOM(Out Of Memory)。例如,一個應用程式實際需要使用2個小頁面,即8 KiB記憶體,但是核心分配了1個透明大頁。此時,除去應用程式實際需要的記憶體(2個小頁面),透明大頁剩下的記憶體(510個小頁面)大小均為0。最終可能會因RSS(Resident Set Size)記憶體用量增加而導致OOM。

為解決THP可能引發的記憶體問題。Alibaba Cloud Linux增加了memcg粒度的THP reclaim功能。在核心回收記憶體時,該功能會把透明大頁面分割為小頁面,並將其中的全零頁面(zero subpage)回收,從而避免記憶體的快速膨脹引發OOM。但您需要注意,由於THP reclaim功能會將透明大頁面分割為小頁面,所以相較於2 MiB大小的透明大頁,THP reclaim功能會在一定程度上造成記憶體效能的回退。

介面說明

實現THP reclaim功能的介面說明,如下表所述:

介面

說明

memory.thp_reclaim

開啟或關閉THP reclaim功能。支援以下配置項:

  • reclaim:開啟THP reclaim功能。

  • swap:預留配置項,目前暫無實際功能。

  • disable:關閉THP reclaim功能。

THP reclaim功能預設為關閉狀態,即介面預設值為disable。

memory.thp_reclaim_stat

查看THP reclaim功能當前的狀態。介面內的參數說明如下:

  • queue_length:當前被THP reclaim管理的透明大頁數量。

  • split_hugepage:累計拆分的透明大頁數量。

  • reclaim_subpage:累計回收的全零頁面數量。

該介面的參數值按照NUMA node的順序(node0、node1)從左至右排列。

memory.thp_reclaim_ctrl

控制THP reclaim功能的觸發機制。目前支援以下配置項:

  • threshold:預設值為16。表示當透明大頁中的全零頁面數量超過該值時,會觸發THP reclaim功能。

  • reclaim:用於主動觸發THP reclaim功能。

/sys/kernel/mm/transparent_hugepage/reclaim

THP reclaim功能的全域配置介面。支援以下配置項:

  • memcg:該介面的預設配置項。表示每個memory cgroup按照各自的配置開啟或關閉THP reclaim,即以每個memory cgroup中的memory.thp_reclaim介面配置為準。

  • reclaim:強制開啟所有memory cgroup的THP reclaim功能。

  • swap:預留配置項,目前暫無實際功能。

  • disable:強制關閉所有memory cgroup的THP reclaim功能。

功能限制

僅以下核心版本的Alibaba Cloud Linux鏡像支援配置THP reclaim功能:

  • Alibaba Cloud Linux 2:4.19.91-24.al7及以上核心版本。

  • Alibaba Cloud Linux 3:5.10.134-15.al8及以上核心版本。

說明

您可以通過uname -r命令查詢鏡像的核心版本。

配置THP reclaim功能

本樣本操作中,將以建立一個名為test的memory cgroup為例介紹如何配置THP reclaim。

  1. 運行以下命令,建立一個名為test的memory cgroup。

    sudo mkdir /sys/fs/cgroup/memory/test/
  2. 運行以下命令,開啟test的THP reclaim功能。

    sudo sh -c 'echo reclaim > /sys/fs/cgroup/memory/test/memory.thp_reclaim'
  3. 運行以下命令,確認test的THP reclaim功能成功開啟。

    cat /sys/fs/cgroup/memory/test/memory.thp_reclaim

    返回結果如下圖所示,被[]包裹的配置項為生效配置項,[reclaim]表示test的THP reclaim功能已開啟。

    image

  4. 運行以下命令,通過THP reclaim功能的全域配置介面強制開啟THP reclaim功能。

    sudo sh -c 'echo reclaim > /sys/kernel/mm/transparent_hugepage/reclaim'

    如果您想強制關閉THP reclaim功能,可運行以下命令:

    sudo sh -c 'echo disable > /sys/kernel/mm/transparent_hugepage/reclaim'
    說明

    THP reclaim功能的全域配置介面/sys/kernel/mm/transparent_hugepage/reclaim在設定為強制開啟(reclaim)或強制關閉(disable)時,介面生效的優先順序會高於各個memory cgroup中的memory.thp_reclaim介面,但不會影響各個memory cgroup中memory.thp_reclaim介面的配置。

  5. 運行以下命令,配置testmemory.thp_reclaim_ctrl介面的threshold配置項。

    sudo sh -c 'echo "threshold 32" >  /sys/fs/cgroup/memory/test/memory.thp_reclaim_ctrl'

    該樣本命令表示如果透明大頁中的全零頁面數量超過32,則會觸發THP reclaim的全零頁面回收功能。

  6. 主動觸發THP reclaim的全零頁面回收功能。

    主動觸發後,THP reclaim會把所有超過threshold配置的全零頁面回收。配置項reclaim存在以下配置方式:

    說明

    該配置項的調用方式為同步調用,並且為唯寫配置項,即您只能向memory.thp_reclaim_ctrl介面寫入reclaim以主動觸發THP reclaim的全零頁面回收功能,但不能通過cat命令查看到reclaim配置項。

    • 運行以下命令,會主動觸發當前memory cgroup的THP reclaim的全零頁面回收功能。

      sudo sh -c 'echo "reclaim 1" >  /sys/fs/cgroup/memory/test/memory.thp_reclaim_ctrl'
    • 運行以下命令,會主動遞迴觸發當前memory cgroup以及該cgroup下所有子cgroup的THP reclaim的全零頁面回收功能。

      sudo sh -c 'echo "reclaim 2" >  /sys/fs/cgroup/memory/test/memory.thp_reclaim_ctrl'

      除了通過reclaim主動觸發THP reclaim的全零頁面回收功能。THP reclaim還會伴隨記憶體回收而觸發:

      • 記憶體出現OOM時,會觸發THP reclaim的全零頁面回收功能。

      • 當memory cgroup觸發memory後台非同步回收時,會觸發THP reclaim的全零頁面回收功能。關於memory後台非同步回收的更多資訊,請參見Memcg後台非同步回收

  7. 運行以下命令,查看test的THP reclaim功能狀態。

    cat /sys/fs/cgroup/memory/test/memory.thp_reclaim_stat

    返回結果樣本如下:

    queue_length        14
    split_hugepage     523
    reclaim_subpage 256207

    該結果表示:

    • queue_length表示THP reclaim管理的透明大頁數量為14。

    • split_hugepage表示累計拆分的透明大頁數量為523。

    • reclaim_subpage表示累計回收的全零頁面數量為256207。

測試THP reclaim功能效果

本節基於C語言提供了進程申請透明大頁的代碼測試範例。您可以通過以下測試範例,查看到THP reclaim功能在開啟與關閉時的區別。

  1. 運行以下命令,為記憶體使用量量限制介面memory.limit_in_bytes設定1 GiB的限制。

    sudo sh -c 'echo 1G > /sys/fs/cgroup/memory/test/memory.limit_in_bytes'

    設定後,您可以運行以下命令查看memory.limit_in_bytes介面的值。

    cat /sys/fs/cgroup/memory/test/memory.limit_in_bytes

    查看結果如下圖所示:

    image

  2. 運行以下命令,關閉memcg後台非同步回收功能。

    關於memcg後台非同步回收的更多資訊,請參見Memcg後台非同步回收

    sudo sh -c 'echo 0 > /sys/fs/cgroup/memory/test/memory.wmark_ratio'
  3. 分別在開啟或關閉THP reclaim功能的前提下,運行以下命令對C語言代碼進行測試,並查看測試結果。

    gcc -o test <test.c>

    其中,<test.c>的程式碼範例如下,您可以根據實際需求替換。

    // 申請1 G記憶體(即512個透明大頁),其中10個透明大頁包含部分全零頁面。
    #include <stdlib.h>  // For posix_memalign
    #include <string.h>  // For memset
    #include <unistd.h>  // For pause
    
    #define HUGEPAGE_SIZE 4096 * 512
    int main()
    {
            int i, thp = 512;
            char *addr;
            posix_memalign((void **)&addr, HUGEPAGE_SIZE, HUGEPAGE_SIZE * thp);
    
            for (i = 0; i < 10; i++) {
                    memset(addr, 0xc, HUGEPAGE_SIZE >> 1);
                    addr += HUGEPAGE_SIZE;
            }
    
            for (; i < thp; i++) {
                    memset(addr, 0xc, HUGEPAGE_SIZE);
                    addr += HUGEPAGE_SIZE;
            }
    
            pause();
            return 0;
    }

    在測試過程中,您可以在另一台終端通過dmesg -wH命令同步監控系統是否發生OOM事件和記憶體使用量情況。測試結果根據THP reclaim功能的開啟狀態有所不同:

    • THP reclaim功能開啟:進程申請透明大頁過程中,THP reclaim會把前序申請的透明大頁面分割為小頁,並回收其中的全零頁面,從而減少記憶體的使用量,最終不會發生OOM。

    • THP reclaim功能關閉:系統不會主動拆分和回收全零頁面,最終發生OOM,您將看到核心輸出關於記憶體不足的日誌資訊,包括可能被殺死的進程詳情。

相關文檔