Memory

Cgroup 和程序記憶體統計資訊不匹配

  • January 18, 2022

我正在嘗試設置一些監視以查看服務何時使用過多記憶體。可以從兩個地方讀取記憶體使用情況:

  • 用於/proc/<pid>/statuspid,或
  • 用於執行它的/sys/fs/cgroup/<group-id>/memory.stat對照組。

該服務由 systemd 啟動,因此它擁有自己的控制組,並且因為它有時會啟動我需要包含在統計資訊中的子程序,並且由於路徑在重新啟動時是恆定的,所以控制組統計資訊更合適。

不幸的是,數字似乎不匹配。以下是沒有子程序執行時的值範例(命令與執行完全相同,除了服務名稱,結果與獲取完全相同,除了與記憶體相關的項目被刪除):

# cat /sys/fs/cgroup/system.slice/some.service/memory.stat /proc/$(cat /sys/fs/cgroup/system.slice/some.service/cgroup.procs)/status
anon 5873664
file 2408448
kernel_stack 491520
slab 962560
sock 0
shmem 61440
file_mapped 405504
file_dirty 0
file_writeback 0
inactive_anon 0
active_anon 5853184
inactive_file 1916928
active_file 360448
unevictable 0
slab_reclaimable 270336
slab_unreclaimable 692224
pgfault 60258
pgmajfault 99
pgrefill 0
pgscan 0
pgsteal 0
pgactivate 0
pgdeactivate 0
pglazyfree 0
pglazyfreed 0
workingset_refault 0
workingset_activate 0
workingset_nodereclaim 0
…
VmPeak:   494812 kB
VmSize:   494164 kB
VmLck:         0 kB
VmPin:         0 kB
VmHWM:     25836 kB
VmRSS:     25484 kB
RssAnon:            5468 kB
RssFile:           20016 kB
RssShmem:              0 kB
VmData:   464776 kB
VmStk:       132 kB
VmExe:       180 kB
VmLib:     23940 kB
VmPTE:       156 kB
VmSwap:        0 kB
voluntary_ctxt_switches:        9
nonvoluntary_ctxt_switches:     620

我會認為過程統計中的適當值是VmRSS(= RssAnon+ RssFile+ RssShmem)。但是,雖然我認為anon小組應該RssAnon屬於過程,file小組應該RssFile屬於過程,但它們並不匹配。雖然anon是 5736 KB,RssAnon但只有 5468 KB,而對於文件來說差異更大,file只有 2352 KB,但RssFile為 20016 KB,幾乎是數量級的差異。

還有memory.current一個值與anon+ file+ kernel_stack+ slab+ sock+大致匹配的文件shmem,但我在程序狀態中看不到任何匹配值。

那麼為什麼這些數字如此不同,哪些數字更能說明應用程序對系統施加的記憶體壓力呢?

注意:在核心 4.19.72(稍微陳舊的嵌入式 BSP)上使用 cgroup2。

來自控制組 v2指南:

**一個記憶體區域被實例化它的 cgroup 負責,**並一直由 cgroup 負責,直到該區域被釋放。將程序遷移到不同的 cgroup 不會將它在前一個 cgroup 中實例化的記憶體使用量移動到新的 cgroup。

屬於不同 cgroup 的程序可以使用記憶體區域。該區域將向哪個 cgroup 收費是不確定的;然而,隨著時間的推移,記憶體區域很可能最終會出現在一個有足夠記憶體餘量以避免高回收壓力的 cgroup 中。

file因此,我們將從in cgroups 和RssFilein之間的區別開始/proc/<pid>/status

該程序可能已經打開了 20016 KB 的文件,但這些文件頁面可能之前已經存在於記憶體記憶體中,因為其他程序已經打開了它們,並且它們各自的 cgroup 對它們收費。因此,在這 20016 KB 中,只有 2352 KB 由 cgroup 收費,其餘的屬於其他 cgroup(以及之前載入這些文件的程序)。

anon關於in cgroups 和RssAnonin之間的區別/proc/<pid>/status,我沒有任何好的解釋。

關於memory.current,據我所知,所有核心內部結構(如kernel_stackslab)僅在 cgroup 中可見,並且您看不到這些數字的每個程序的統計資訊,因為/proc/<pid>/status僅顯示使用者空間記憶體資訊。

引用自:https://unix.stackexchange.com/questions/686814