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功能的介面說明,如下表所述:
介面 | 說明 |
| 開啟或關閉THP reclaim功能。支援以下配置項:
THP reclaim功能預設為關閉狀態,即介面預設值為disable。 |
| 查看THP reclaim功能當前的狀態。介面內的參數說明如下:
該介面的參數值按照NUMA node的順序(node0、node1)從左至右排列。 |
| 控制THP reclaim功能的觸發機制。目前支援以下配置項:
|
| 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。
運行以下命令,建立一個名為test的memory cgroup。
sudo mkdir /sys/fs/cgroup/memory/test/
運行以下命令,開啟test的THP reclaim功能。
sudo sh -c 'echo reclaim > /sys/fs/cgroup/memory/test/memory.thp_reclaim'
運行以下命令,確認test的THP reclaim功能成功開啟。
cat /sys/fs/cgroup/memory/test/memory.thp_reclaim
返回結果如下圖所示,被
[]
包裹的配置項為生效配置項,[reclaim]
表示test的THP reclaim功能已開啟。運行以下命令,通過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
介面的配置。運行以下命令,配置test的
memory.thp_reclaim_ctrl
介面的threshold
配置項。sudo sh -c 'echo "threshold 32" > /sys/fs/cgroup/memory/test/memory.thp_reclaim_ctrl'
該樣本命令表示如果透明大頁中的全零頁面數量超過32,則會觸發THP reclaim的全零頁面回收功能。
主動觸發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後台非同步回收。
運行以下命令,查看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功能在開啟與關閉時的區別。
運行以下命令,為記憶體使用量量限制介面
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
查看結果如下圖所示:
運行以下命令,關閉memcg後台非同步回收功能。
關於memcg後台非同步回收的更多資訊,請參見Memcg後台非同步回收。
sudo sh -c 'echo 0 > /sys/fs/cgroup/memory/test/memory.wmark_ratio'
分別在開啟或關閉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,您將看到核心輸出關於記憶體不足的日誌資訊,包括可能被殺死的進程詳情。