【運維實戰】Linux 內存調優之進程內存深度監控


寫在前面


  • 內容涉及 Linux 進程內存監控

  • 監控方式包括傳統工具?ps/top/pmap?,以及?cgroup?內存子系統,proc?內存偽文件系統

  • 監控內容包括進程內存使用情況?內存全局數據統計內存事件指標,以及進程內存段數據監控

監控進程的內存使用量

這里分析的工具主要是原生工具,后面還會分享一些 BPF 相關的內存觀察工具以及系統內存的全局監控

PS/TOP

一般的內存監控工具,對于進程級別的,會使用如?ps/top?命令, 通過指標?VIRT?或?VSZ?和?RES?或?RSS?來區分兩種不同的統計數據

  • VIRT?或?VSZ?代表進程申請的虛擬內存大小,

  • RES?或?RSS?代表的是虛擬內存當前實際映射的物理內存大小,也叫常駐內存。

┌──[root@vms100.liruilongs.github.io]-[~]
└─$top
top - 11:46:44 up 8 min, ?1 user, ?load average: 6.52, 17.45, 10.38
Tasks: 449 total, ? 1 running, 448 sleeping, ? 0 stopped, ? 0 zombie
%Cpu(s): ?0.9 us, ?1.1 sy, ?0.0 ni, 96.8 id, ?0.0 wa, ?0.6 hi, ?0.5 si, ?0.0 st
MiB Mem : ?15730.5 total, ? 7503.6 free, ? 7147.4 used, ? 1079.5 buff/cache
MiB Swap: ? 2068.0 total, ? 2068.0 free, ? ? ?0.0 used. ? 8177.7 avail MemPID USER ? ? ?PR ?NI ? ?VIRT ? ?RES ? ?SHR S ?%CPU ?%MEM ? ? TIME+ COMMAND1947 42418 ? ? 20 ? 0 ?555196 132972 ?20272 S ? 1.3 ? 0.8 ? 0:12.86 heat-engine10320 42436 ? ? 20 ? 0 ?540276 122200 ?17492 S ? 1.3 ? 0.8 ? 0:08.95 nova-scheduler949 root ? ? ?20 ? 0 ?694072 ?31640 ?16876 S ? 1.0 ? 0.2 ? 0:16.58 tuned1945 42415 ? ? 20 ? 0 ?749212 142564 ?34988 S ? 1.0 ? 0.9 ? 0:12.38 glance-api1965 42436 ? ? 20 ? 0 ?540120 121848 ?17324 S ? 1.0 ? 0.8 ? 0:12.16 nova-conductor15567 root ? ? ?20 ? 0 ?269540 ? 5228 ? 4160 R ? 1.0 ? 0.0 ? 0:00.05 top..........................................

所以如果通過上面的命令,查看應用實際使用的內存大小,需要查看?RES(RSS(KB單位))?列,表示進程當前駐留在物理內存中的內存總量(即沒有被交換到磁盤的部分)。

RSS?包含的內容:

  • 進程獨有的數據(如堆、棧、私有匿名頁)。 + 共享內存頁(如共享庫、共享內存 IPC 等)。

┌──[root@liruilongs.github.io]-[~]
└─$ps?-e -o pid,vsz,rss,comm | awk?'$2 > 0 {print}'PID ? ?VSZ ? RSS COMMAND1 170808 14208 systemd704 ?26824 11520 systemd-journal719 ?34968 12160 systemd-udevd892 ?18156 ?4540 auditd913 ?10796 ?4736 dbus-broker-lau
。。。。。。。。。。4177 ? 6664 ?3712 awk
┌──[root@liruilongs.github.io]-[~]
└─$

共享內存

需要說明的是,進程是共享物理內存頁幀的。比如使用相同庫函數的兩個進程,就可以共享使用相同的物理內存頁來存儲庫文件代碼。它們各自的?RSS(Resident Set Size)?值會將該共享頁的物理內存(SHR 列)重復計入每個進程的?RSS(RES)。因此 進程的?RSS 總和 可能會明顯超過 系統實際的物理內存容量真實物理內存占用 = ?獨占內存(RES) - 共享內存SHR(Shared Memory)

SHR列 :進程占用的 共享物理內存(如共享庫、共享內存 IPC)。

Cgroup 子系統

通過?Cgroup?子系統來獲取內存信息,在獲取之前需要獲取當前進程的PID以及對應的?Cgroup?分組

獲取?htop?進程ID, htop 是一個類似 top 的系統整體性能監控的進程

┌──[root@liruilongs.github.io]-[/usr/lib/systemd/system]?
└─$pgrep?htop
4150

通過 ps 命令獲取 htop 對應的 Cgroup 分組

┌──[root@liruilongs.github.io]-[/usr/lib/systemd/system]?
└─$ps?-o cgroup 4150
CGROUP
11:pids:/user.slice/user-1000.slice/session-1.scope,
8:memory:/user.slice/user-1000.slice/session-1.scope,
2:devices:/user.slice,
1:name=systemd:/user.slice/user-1000.sli
┌──[root@liruilongs.github.io]-[/usr/lib/systemd/system]?
└─$

我們只關注內存子系統的,所以直接看內存的分組:?8:memory:/user.slice/user-1000.slice/session-1.scope,這里的 8 表示 Cgroup 層級

可以通過下面的命令查看?Cgroup?層級以及 當前系統掛載了多少子系統

┌──[root@liruilongs.github.io]-[/usr/lib/systemd/system]?
└─$cat?/proc/cgroups
#subsys_name hierarchy num_cgroups enabled
cpuset 4 1 1
cpu ? ? 6 3 1
cpuacct 6 3 1
blkio ? 9 1 1
memory 8 91 1
devices 2 43 1
freezer 13 1 1
net_cls 12 1 1
perf_event 5 1 1
net_prio 12 1 1
hugetlb 7 1 1
pids 11 52 1
rdma 3 1 1
files 10 1 1
┌──[root@liruilongs.github.io]-[/usr/lib/systemd/system]?
└─$

user.slice/user-1000.slice/session-1.scope?表示 Cgroup 層級樹

  • user.slice:表示該 cgroup 屬于 用戶會話層級,與用戶進程相關(與 system.slice 系統服務層級區分)

  • user-1000.slice:表示用戶 ID 為 1000 的普通用戶(Linux 中 UID 1000 通常是首個創建的非 root 用戶)

  • session-1.scope:表示該用戶的 會話單元(如一個終端會話或登錄會話),屬于臨時性資源組(scope 用于管理短生命周期的進程組)

htop?是一個前臺進程,通過?Cgroup?資源樹可以很清晰的看到,下面來看下?Cgroup?內存子系統觀察進程內存信息的一些指標文件

內存詳細信息指標監控

下面一組是內存詳細信息的數據統計

參數

作用

memory.numa_statNUMA 節點的內存使用統計

(適用于多 CPU 架構)。

memory.stat詳細內存使用統計

在這之前我們先介紹一個特殊的值,memory.limit_in_bytes?這個可能是我們接觸最多的參數,用于進程 物理內存資源限制

┌──[root@liruilongs.github.io]-[/usr/lib/systemd/system]?
└─$cat?/sys/fs/cgroup/memory/user.slice/user-1000.slice/session-1.scope/memory.limit_in_bytes
9223372036854771712

可以看到上面的 htop, 文件中的值?9223372036854771712?表示當前?cgroup?的內存限制處于無限制狀態,當?cgroup?未顯式設置內存限制時,內核會默認將此值設為?PAGE_COUNTER_MAX,該值由內核通過?LONG_MAX / PAGE_SIZE * PAGE_SIZE?計算得出,確保與內存頁對齊.

memory.stat

┌──[root@liruilongs.github.io]-[/usr/lib/systemd/system]?
└─$cat?/sys/fs/cgroup/memory/user.slice/user-1000.slice/session-1.scope/memory.stat?
cache 393973760
rss 301170688
rss_huge 171966464
shmem 847872
mapped_file 86605824
dirty 8192
writeback 0
swap 0
pgpgin 241505
pgpgout 113977
pgfault 231305
pgmajfault 260
inactive_anon 302727168
active_anon 147456
inactive_file 348233728
active_file 44892160
unevictable 0
hierarchical_memory_limit 9223372036854771712
hierarchical_memsw_limit 9223372036854771712
total_cache 393973760
total_rss 301170688
total_rss_huge 171966464
total_shmem 847872
total_mapped_file 86605824
total_dirty 8192
total_writeback 0
total_swap 0
total_pgpgin 241505
total_pgpgout 113977
total_pgfault 231305
total_pgmajfault 260
total_inactive_anon 302727168
total_active_anon 147456
total_inactive_file 348233728
total_active_file 44892160
total_unevictable 0
┌──[root@liruilongs.github.io]-[/usr/lib/systemd/system]?
└─$

以下是關鍵參數的說明


memory.stat?核心參數解析表

參數分類參數名值(字節)說明相關引用
基礎內存使用cache

393,973,760

文件緩存和 tmpfs/shmem 內存,用于加速文件訪問(可回收)

rss

301,170,688

進程匿名內存(堆、棧等)占用,反映實際物理內存使用量

swap

0

當前 cgroup 使用的交換空間大小,非零表示物理內存不足

內存頁管理active_anon

147,456

活躍的匿名內存頁(正在使用的堆、棧內存)

inactive_anon

302,727,168

非活躍的匿名內存頁(可被回收的堆、棧內存)

active_file

44,892,160

活躍的文件緩存頁(近期被頻繁訪問的文件數據)

inactive_file

348,233,728

非活躍的文件緩存頁(長時間未訪問的文件數據,優先回收)

內存事件pgpgin

241,505

從磁盤換入內存的頁數,高值可能反映頻繁 I/O

pgpgout

113,977

從內存換出到磁盤的頁數

pgmajfault

260

需磁盤 I/O 的硬缺頁次數,高值可能引發性能問題

層級管理hierarchical_memory_limit

9,223,372,036...

層級化內存限制(當前值為極大數,表示未啟用限制)

total_*

?系列(如?total_rss

與同名參數一致

包含當前 cgroup 及其子 cgroup 的總統計值(如?total_rss?表示層級內所有進程的匿名內存總和)

其他rss_huge

171,966,464

透明大頁(THP)占用量,大頁可減少內存管理開銷

unevictable

0

不可回收的內存(如?mlock?鎖定的內存)


  1. 單位與換算:上述值均為?字節(Bytes),可通過?1 GB = 1073741824 Bytes?轉換為更易讀的單位。例如: ??cache = 393,973,760 Bytes ≈ 376 MB??rss = 301,170,688 Bytes ≈ 287 MB

  2. 關鍵場景判斷: ??內存壓力:若?rss?接近?hierarchical_memory_limit,需警惕 OOM(內存耗盡)風險。 ??緩存優化:若?inactive_file?較高,可通過?sync; echo 3 > /proc/sys/vm/drop_caches?手動回收緩存。

  3. 與?free/vmstat?的關系: ??free -m?中的?buff/cache?對應?cache + buff(部分系統可能合并統計)。 ??vmstat?的?si/so?對應?pgpgin/pgpgout?的實時動態變化。

如需進一步分析具體進程的內存行為,可結合?/proc/<PID>/smaps?或工具如?smem

memory.numa_stat

┌──[root@liruilongs.github.io]-[/usr/lib/systemd/system]?
└─$cat?/sys/fs/cgroup/memory/user.slice/user-1000.slice/session-1.scope/memory.numa_stat?
total=169929 N0=169929
file=95978 N0=95978
anon=73951 N0=73951
unevictable=0 N0=0
hierarchical_total=169929 N0=169929
hierarchical_file=95978 N0=95978
hierarchical_anon=73951 N0=73951
hierarchical_unevictable=0 N0=0
┌──[root@liruilongs.github.io]-[/usr/lib/systemd/system]?
└─$

以下是對?memory.numa_stat?輸出參數的詳細解釋

參數名類型描述

total

基礎統計項

當前 cgroup 在 NUMA 節點上的總內存占用(單位字節),等于?anon?+?file?+?unevictable?之和

file

基礎統計項

文件頁緩存(File-backed memory)占用量,例如程序文件、共享庫等通過文件映射的內存

anon

基礎統計項

匿名頁(Anonymous pages)和 Swap 緩存的總量,例如堆、棧等動態分配的內存

unevictable

基礎統計項

不可回收的內存頁(例如被鎖定或標記為不可回收的頁面)

hierarchical_total

層級統計項

包含所有子 cgroup 的總內存占用(單位字節),統計范圍覆蓋當前 cgroup 及其子級

hierarchical_file

層級統計項

包含所有子 cgroup 的文件頁緩存總量

hierarchical_anon

層級統計項

包含所有子 cgroup 的匿名頁和 Swap 緩存總量

hierarchical_unevictable

層級統計項

包含所有子 cgroup 的不可回收內存總量

補充說明:

  1. NUMA 節點標識:輸出中的?N0=169929?表示當前統計值屬于 NUMA 節點 0(N0)。在 NUMA 架構中,每個節點的本地內存訪問速度更快,跨節點訪問會增加延遲。

  2. 層級統計的意義: 帶?hierarchical_?前綴的參數表示當前 cgroup 及其所有子 cgroup 的累積內存使用量。例如,hierarchical_total?是當前 cgroup 和子 cgroup 在所有 NUMA 節點上的內存總量。

  3. 應用場景:通過對比?total?和?hierarchical_total,可判斷子 cgroup 的內存分配是否合理。若?unevictable?值較高,可能需排查是否有進程誤用內存鎖定(如?mlock)。

上面的輸出信息中提供的輸出中,total=169929 N0=169929?表示該 cgroup 僅在 NUMA 節點 0 上分配了 169,929 字節內存。其中:

? 文件頁緩存占 95,978 字節(file=95978),
? 匿名頁和 Swap 緩存占 73,951 字節(anon=73951),
? 無不可回收內存(unevictable=0)。

內存事件指標監控

下面為內存事件指標依次來看一下

參數

作用

memory.usage_in_bytes當前物理內存使用量

(包括匿名內存、文件緩存等)。

memory.memsw.usage_in_bytes當前物理內存 + swap 總使用量

memory.failcnt記錄內存限制觸發的失敗次數

(超出?memory.limit_in_bytes?的次數)。

memory.events內存事件計數器

(如?oom?溢出次數、under_oom?低內存狀態)。

memory.events.local

同上,但僅統計當前 cgroup(不包含子 cgroup)。

這里我們使用?tuned?這個服務,這是一個系統調優的服務,作為一個獨立的?service unit?存在,所以會有一個單獨?Cgroup?分組

┌──[root@liruilongs.github.io]-[/usr/lib/systemd/system]?
└─$pgrep?tuned
3654
┌──[root@liruilongs.github.io]-[/usr/lib/systemd/system]?
└─$ps?-o cgroup 3654
CGROUP
11:pids:/system.slice/tuned.service,
8:memory:/system.slice/tuned.service,
2:devices:/system.slice/tuned.service,
1:name=systemd:/system.slice/tuned.service
┌──[root@liruilongs.github.io]-[/usr/lib/systemd/system]?
└─$

可以在?Cgroup?路徑下面看到所有的指標數據?/sys/fs/cgroup/memory/system.slice/tuned.service/,還有部分內核相關的,這里我們只看一下內存相關的

┌──[root@liruilongs.github.io]-[/usr/lib/systemd/system]?
└─$cat?/sys/fs/cgroup/memory/system.slice/tuned.service/
cgroup.clone_children ? ? ? ? ? ? ? memory.kmem.limit_in_bytes ? ? ? ? ?memory.max_usage_in_bytes ? ? ? ? ? memory.pressure_level
cgroup.event_control ? ? ? ? ? ? ? ?memory.kmem.max_usage_in_bytes ? ? ?memory.memfs_files_info ? ? ? ? ? ? memory.qos_level
cgroup.kill ? ? ? ? ? ? ? ? ? ? ? ? memory.kmem.slabinfo ? ? ? ? ? ? ? ?memory.memsw.failcnt ? ? ? ? ? ? ? ?memory.soft_limit_in_bytes
cgroup.procs ? ? ? ? ? ? ? ? ? ? ? ?memory.kmem.tcp.failcnt ? ? ? ? ? ? memory.memsw.limit_in_bytes ? ? ? ? memory.stat
memory.events ? ? ? ? ? ? ? ? ? ? ? memory.kmem.tcp.limit_in_bytes ? ? ?memory.memsw.max_usage_in_bytes ? ? memory.swappiness
memory.events.local ? ? ? ? ? ? ? ? memory.kmem.tcp.max_usage_in_bytes ?memory.memsw.usage_in_bytes ? ? ? ? memory.usage_in_bytes
memory.failcnt ? ? ? ? ? ? ? ? ? ? ?memory.kmem.tcp.usage_in_bytes ? ? ?memory.min ? ? ? ? ? ? ? ? ? ? ? ? ?memory.use_hierarchy
memory.force_empty ? ? ? ? ? ? ? ? ?memory.kmem.usage_in_bytes ? ? ? ? ?memory.move_charge_at_immigrate ? ? notify_on_release
memory.high ? ? ? ? ? ? ? ? ? ? ? ? memory.limit_in_bytes ? ? ? ? ? ? ? memory.numa_stat ? ? ? ? ? ? ? ? ? ?tasks
memory.kmem.failcnt ? ? ? ? ? ? ? ? memory.low ? ? ? ? ? ? ? ? ? ? ? ? ?memory.oom_control

memory.usage_in_bytes?: 當前 cgroup 中所有進程實際使用的物理內存總量(包括 RSS 和 Page Cache),單位字節(約 15.86 MB)。

┌──[root@liruilongs.github.io]-[/usr/lib/systemd/system]?
└─$cat?/sys/fs/cgroup/memory/system.slice/tuned.service/memory.usage_in_bytes?
16629760

memory.memsw.usage_in_bytes?: 當前 cgroup 中所有進程使用的物理內存 + Swap 空間的總量(單位字節)。此處與物理內存相等,說明未使用 Swap。

┌──[root@liruilongs.github.io]-[/usr/lib/systemd/system]?
└─$cat?/sys/fs/cgroup/memory/system.slice/tuned.service/memory.memsw.usage_in_bytes
16629760

memory.failcnt?存使用達到?memory.limit_in_bytes?設定的限制值的次數。值為 0 表示未觸發過內存超限。

┌──[root@liruilongs.github.io]-[/usr/lib/systemd/system]?
└─$cat?/sys/fs/cgroup/memory/system.slice/tuned.service/memory.failcnt
0

memory.events 內存事件計數器:

  • low: 低內存壓力事件次數

  • high: 高內存壓力事件次數

  • limit_in_bytes: 達到內存限制的次數

  • oom: OOM(內存耗盡)觸發次數。全為 0 表示無相關事件發生。

┌──[root@liruilongs.github.io]-[/usr/lib/systemd/system]?
└─$cat?/sys/fs/cgroup/memory/system.slice/tuned.service/memory.events
low 0
high 0
limit_in_bytes 0
oom 0
┌──[root@liruilongs.github.io]-[/usr/lib/systemd/system]?
└─$

當然還有一些其他的參數,感興小伙伴可以研究下,通過去讀上面的參數可以進行性能分析,系統監控

proc 內存偽文件系統

如果需要詳細查看一個進程使用了哪些虛擬地址,可用使用?pmap PID?命令或者基于?proc?內存偽文件系統查看內存詳細信息,比如?/proc/1/status,/proc/PID/maps?和/proc/PID/smaps等,

查看進程詳細內存段數據

pmap 1002

快速查看進程的虛擬內存布局和總占用。

┌──[root@liruilongs.github.io]-[~]
└─$pmap?1002
1002: ? /usr/bin/python3 -Es /usr/sbin/tuned -l -P
0000561ae3586000 ? ? ?4K r---- python3.9?# 文件路徑
0000561ae3587000 ? ? ?4K r-x-- python3.9
0000561ae3588000 ? ? ?4K r---- python3.9
0000561ae3589000 ? ? ?4K r---- python3.9
。。。。。。。。。。。。。。。。
00007ffc6f79b000 ? ?132K rw--- ? [ stack ]?#進程棧。
00007ffc6f7ce000 ? ? 16K r---- ? [ anon ]?#匿名內存(堆、棧等)
00007ffc6f7d2000 ? ? ?8K r-x-- ? [ anon ]
ffffffffff600000 ? ? ?4K --x-- ? [ anon ]total ? ? ? ? ? 256364K
┌──[root@liruilongs.github.io]-[~]
└─$

對應的列分別表示:內存段的起始虛擬地址(如 0000561ae3586000)。內存段的大小(如 4K)。內存訪問權限 (r)可讀 |(w)可寫 |(x)可執行 |(s)共享 |(p)私有

/proc/1/maps

詳細列出所有內存段的地址范圍、權限和映射文件

┌──[root@liruilongs.github.io]-[~]
└─$cat?/proc/1/maps | head -20
55e05a46b000-55e05a471000 r--p 00000000 fd:00 372298 ? ? ? ? ? ? ? ? ? ? /usr/lib/systemd/systemd
55e05a471000-55e05a47c000 r-xp 00006000 fd:00 372298 ? ? ? ? ? ? ? ? ? ? /usr/lib/systemd/systemd
55e05a47c000-55e05a481000 r--p 00011000 fd:00 372298 ? ? ? ? ? ? ? ? ? ? /usr/lib/systemd/systemd
55e05a482000-55e05a483000 r--p 00016000 fd:00 372298 ? ? ? ? ? ? ? ? ? ? /usr/lib/systemd/systemd
55e05a483000-55e05a484000 rw-p 00017000 fd:00 372298 ? ? ? ? ? ? ? ? ? ? /usr/lib/systemd/systemd
55e05af99000-55e05b2a3000 rw-p 00000000 00:00 0 ? ? ? ? ? ? ? ? ? ? ? ? ?[heap]
7ff43c000000-7ff43c021000 rw-p 00000000 00:00 0
7ff43c021000-7ff440000000 ---p 00000000 00:00 0
7ff444000000-7ff444021000 rw-p 00000000 00:00 0
7ff444021000-7ff448000000 ---p 00000000 00:00 0
7ff44b761000-7ff44b762000 ---p 00000000 00:00 0
7ff44b762000-7ff44bf62000 rw-p 00000000 00:00 0
7ff44bf62000-7ff44bf63000 ---p 00000000 00:00 0
7ff44bf63000-7ff44c766000 rw-p 00000000 00:00 0
7ff44c766000-7ff44c768000 r--p 00000000 fd:00 33948825 ? ? ? ? ? ? ? ? ? /usr/lib64/libffi.so.8.1.0
7ff44c768000-7ff44c76e000 r-xp 00002000 fd:00 33948825 ? ? ? ? ? ? ? ? ? /usr/lib64/libffi.so.8.1.0
7ff44c76e000-7ff44c76f000 r--p 00008000 fd:00 33948825 ? ? ? ? ? ? ? ? ? /usr/lib64/libffi.so.8.1.0
7ff44c76f000-7ff44c770000 ---p 00009000 fd:00 33948825 ? ? ? ? ? ? ? ? ? /usr/lib64/libffi.so.8.1.0
7ff44c770000-7ff44c771000 r--p 00009000 fd:00 33948825 ? ? ? ? ? ? ? ? ? /usr/lib64/libffi.so.8.1.0
7ff44c771000-7ff44c772000 rw-p 0000a000 fd:00 33948825 ? ? ? ? ? ? ? ? ? /usr/lib64/libffi.so.8.1.0

可以看到在上面的基礎上,展示了內存段的起始和結束虛擬地址(如 55e05a46b000-55e05a471000)。多了映射文件在文件中的偏移量(十六進制,如 00000000)。文件所在設備的編號(格式 fd:00,主設備號:次設備號)。文件的?inode 編號(如 372298)

/proc/1/smaps

提供每個內存段的詳細物理內存統計(RSS、PSS、共享/私有內存等)

┌──[root@liruilongs.github.io]-[~]
└─$cat?/proc/1/smaps | head -30
55e05a46b000-55e05a471000 r--p 00000000 fd:00 372298 ? ? ? ? ? ? ? ? ? ? /usr/lib/systemd/systemd
Size: ? ? ? ? ? ? ? ? 24 kB
KernelPageSize: ? ? ? ?4 kB
MMUPageSize: ? ? ? ? ? 4 kB
Rss: ? ? ? ? ? ? ? ? ?24 kB
Pss: ? ? ? ? ? ? ? ? ? 7 kB
Shared_Clean: ? ? ? ? 24 kB
Shared_Dirty: ? ? ? ? ?0 kB
Private_Clean: ? ? ? ? 0 kB
Private_Dirty: ? ? ? ? 0 kB
Referenced: ? ? ? ? ? 24 kB
Anonymous: ? ? ? ? ? ? 0 kB
LazyFree: ? ? ? ? ? ? ?0 kB
AnonHugePages: ? ? ? ? 0 kB
ShmemPmdMapped: ? ? ? ?0 kB
FilePmdMapped: ? ? ? ? 0 kB
Shared_Hugetlb: ? ? ? ?0 kB
Private_Hugetlb: ? ? ? 0 kB
Swap: ? ? ? ? ? ? ? ? ?0 kB
SwapPss: ? ? ? ? ? ? ? 0 kB
Locked: ? ? ? ? ? ? ? ?0 kB
THPeligible: ? ?0
VmFlags: rd mr mw me sd
55e05a471000-55e05a47c000 r-xp 00006000 fd:00 372298 ? ? ? ? ? ? ? ? ? ? /usr/lib/systemd/systemd
Size: ? ? ? ? ? ? ? ? 44 kB
KernelPageSize: ? ? ? ?4 kB
┌──[root@liruilongs.github.io]-[~]
└─$

部分字段說明:

  • Size: 內存段的虛擬大小(如 24 kB)。

  • Rss:(Resident Set Size) 實際占用的物理內存(包含共享內存)。

  • Pss:(Proportional Set Size) 按共享比例計算的物理內存(如 3 個進程共享 24KB → 每個進程 Pss 8KB)。

  • Shared_Clean/Shared_Dirty: 共享內存中未修改/已修改的部分。

  • Private_Clean/Private_Dirty: 私有內存中未修改/已修改的部分。

  • Swap: 被交換到磁盤的內存大小。

  • VmFlags: 內存段的屬性標志(如 rd 可讀,mr 可映射,mw 可寫等)。

進程全局內存數據統計

status?用于展示當前進程的一些基本指標,進程基礎信息,權限與身份,信號與中斷等

┌──[root@liruilongs.github.io]-[/usr/lib/systemd/system]?
└─$cat? /proc/1/status?
Name: systemd
Umask: 0000
State: S (sleeping)
Tgid: 1
Ngid: 0
Pid: 1
PPid: 0
TracerPid: 0
Uid: 0 0 0 0
Gid: 0 0 0 0
FDSize: 256
Groups: ?
NStgid: 1
NSpid: 1
NSpgid: 1
NSsid: 1
VmPeak: ? 165112 kB
VmSize: ? 100636 kB
VmLck: ? ? ? ?0 kB
VmPin: ? ? ? ?0 kB
VmHWM: ? ?12688 kB
VmRSS: ? ?12688 kB
RssAnon: ? ? 4084 kB
RssFile: ? ? 8604 kB
RssShmem: ? ? ? ?0 kB
VmData: ? ?19052 kB
VmStk: ? ? 1036 kB
VmExe: ? ? ?884 kB
VmLib: ? ? 8832 kB
VmPTE: ? ? ? 84 kB
VmSwap: ? ? ? ?0 kB
HugetlbPages: ? ? ? ?0 kB
CoreDumping: 0
THP_enabled: 1
Threads: 1
SigQ: 0/29616
SigPnd: 0000000000000000
ShdPnd: 0000000000000000
SigBlk: 7be3c0fe28014a03
SigIgn: 0000000000001000
SigCgt: 00000001000004ec
CapInh: 0000000000000000
CapPrm: 000001ffffffffff
CapEff: 000001ffffffffff
CapBnd: 000001ffffffffff
CapAmb: 0000000000000000
NoNewPrivs: 0
Seccomp: 0
Seccomp_filters: 0
Speculation_Store_Bypass: thread vulnerable
Cpus_allowed: f
Cpus_allowed_list: 0-3
Mems_allowed: 00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000001
Mems_allowed_list: 0
voluntary_ctxt_switches: 2558
nonvoluntary_ctxt_switches: 483

這里只關注內存相關的

虛擬內存核心指標

參數描述

VmPeak

165,112 kB

進程生命周期內虛擬內存的?峰值(含已分配但未使用的內存),反映進程曾達到的最大內存需求

VmSize

100,636 kB

當前進程?虛擬地址空間總大小(包括代碼、數據、堆、棧等所有映射區域),約 98.27 MB

物理內存核心指標

參數描述

VmHWM

12,688 kB

進程物理內存使用?峰值(Resident Set Size 最大值),約 12.38 MB

VmRSS

12,688 kB

當前實際駐留物理內存(RSS),等于?RssAnon?+?RssFile?+?RssShmem,約 12.38 MB

RssAnon

4,084 kB

匿名頁(動態分配的堆/棧內存)占用的物理內存,例如?malloc?分配的未映射文件的內存

RssFile

8,604 kB

文件頁緩存占用的物理內存(如加載的共享庫、內存映射文件)

RssShmem

0 kB

共享內存段(如?shmget?創建的 IPC 內存)占用的物理內存

內存區域細分指標

參數描述

VmData

19,052 kB

數據段 + 堆

?的虛擬內存大小(動態分配的內存通過?brk?或?mmap?擴展)

VmStk

1,036 kB

棧空間

?的虛擬內存大小(存放局部變量和函數調用幀),默認上限由?ulimit -s?控制

VmExe

884 kB

可執行代碼段

?的虛擬內存大小(程序本身的機器指令,只讀)

VmLib

8,832 kB

共享庫

?的虛擬內存大小(如?glibc?等動態鏈接庫)

其他關鍵參數

參數描述

VmLck

0 kB

鎖定的物理內存

(通過?mlock?系統調用防止被換出到 Swap),常用于實時性要求高的場景

VmPTE

84 kB

頁表項

?占用的物理內存(用于管理虛擬地址到物理地址的映射關系)

VmSwap

0 kB

當前已換出到?Swap 分區?的內存大小(若值持續增長,需排查內存泄漏或物理內存不足)

關鍵應用場景分析

內存泄漏檢測

  • 對比?VmSize?和?VmRSS:若?VmSize?持續增長而?VmRSS?穩定,可能為虛擬內存分配過多但未實際使用(如未初始化的?malloc)。

  • 監控?VmSwap:若長期非零,需檢查物理內存是否不足或進程存在內存濫用。

性能優化方向

  • 共享庫優化VmLib?值較高時,可考慮靜態鏈接或減少動態庫依賴以降低內存開銷。

  • 堆棧管理VmData?和?VmStk?異常增長可能提示堆內存泄漏或遞歸調用過深。

系統資源分配

  • VmHWM?可用于設置 CGroup 內存限制(memory.max_usage_in_bytes),避免單個進程耗盡物理內存。

  • RssFile?較高時,可通過清理緩存(sync; echo 1 > /proc/sys/vm/drop_caches)釋放非關鍵文件緩存。


statm?用于展示進程內存快照,但需注意 單位是內存頁,通常 1 頁 = 4 KB

┌──[root@liruilongs.github.io]-[/usr/lib/systemd/system]?
└─$cat? /proc/1/statm
25159 3172 2151 221 0 5022 0

字段解析

參數描述換算為 KB

size

25159

進程虛擬地址空間總大小(含代碼、數據、堆棧等所有映射區域)

25159 × 4 ≈ 100,636 KB

Resident

3172

實際駐留物理內存(RSS),即當前進程使用的物理內存總量

3172 × 4 ≈ 12,688 KB

Shared

2151

共享內存頁數(如動態鏈接庫、共享內存段等被多個進程共享的部分)

2151 × 4 ≈ 8,604 KB

Trs

221

可執行代碼段(Text Resident Set)占用的內存頁(如程序自身的機器指令)

221 × 4 ≈ 884 KB

Lrs

0

庫的內存頁數(Linux 2.6+ 中已廢棄,通常為 0)

-

Drs

5022

數據段(堆、全局變量)和用戶態棧的總內存頁

5022 × 4 ≈ 20,088 KB

dt

0

臟頁數量(已修改但未寫入磁盤的頁,Linux 2.6+ 中已廢棄)

-

與?/proc/1/status?的關聯?對比?/proc/1/status?中的內存參數可驗證數據一致性

??VmSize:?100636 kB?=?size × 4?=?25159 × 4
??VmRSS:?12688 kB?=?Resident × 4?=?3172 × 4
??RssFile:?8604 kB?≈?Shared × 4?=?2151 × 4
??VmExe:?884 kB?=?Trs × 4?=?221 × 4
??VmData + VmStk:?19052 + 1036 = 20088 kB?≈?Drs × 4?=?5022 × 4

smaps_rollup?提供進程 全局匯總統計(如總 RSS、PSS、Swap 等), 讀取?smaps_rollup?比遍歷?smaps?更高效(減少鎖競爭時間),適合高頻監控場景,

┌──[root@liruilongs.github.io]-[/usr/lib/systemd/system]?
└─$cat? /proc/1/smaps_rollup?
56476fafe000-7ffc5b7f8000 ---p 00000000 00:00 0 ? ? ? ? ? ? ? ? ? ? ? ? ?[rollup]
Rss: ? ? ? ? ? ? ? 12692 kB
Pss: ? ? ? ? ? ? ? ?4648 kB
Pss_Anon: ? ? ? ? ? 3463 kB
Pss_File: ? ? ? ? ? 1184 kB
Pss_Shmem: ? ? ? ? ? ? 0 kB
Shared_Clean: ? ? ? 8540 kB
Shared_Dirty: ? ? ? ?936 kB
Private_Clean: ? ? ? ?64 kB
Private_Dirty: ? ? ?3152 kB
Referenced: ? ? ? ?12692 kB
Anonymous: ? ? ? ? ?4088 kB
LazyFree: ? ? ? ? ? ? ?0 kB
AnonHugePages: ? ? ? ? 0 kB
ShmemPmdMapped: ? ? ? ?0 kB
FilePmdMapped: ? ? ? ? 0 kB
Shared_Hugetlb: ? ? ? ?0 kB
Private_Hugetlb: ? ? ? 0 kB
Swap: ? ? ? ? ? ? ? ? ?0 kB
SwapPss: ? ? ? ? ? ? ? 0 kB
Locked: ? ? ? ? ? ? ? ?0 kB

核心內存統計

參數描述

Rss

12,692 kB

常駐物理內存總量

(包含共享和私有內存),等于?Shared_Clean + Shared_Dirty + Private_Clean + Private_Dirty

Pss

4,648 kB

比例集內存

(按共享比例分攤后的內存),Pss = Pss_Anon + Pss_File + Pss_Shmem

Pss_Anon

3,463 kB

匿名頁(如堆、棧)分攤后的內存,反映獨占或部分共享的匿名內存

Pss_File

1,184 kB

文件頁緩存(如共享庫、映射文件)分攤后的內存

Pss_Shmem

0 kB

共享內存(如?tmpfs)的分攤內存,此處未使用

共享與私有內存分布

參數描述

Shared_Clean

8,540 kB

共享的未修改內存(如只讀共享庫),可被內核直接回收

Shared_Dirty

936 kB

共享的已修改內存(如被多個進程寫入的共享內存),需同步到磁盤后才能回收

Private_Clean

64 kB

私有的未修改內存(如未修改的私有數據),可快速回收

Private_Dirty

3,152 kB

私有的已修改內存(如進程堆內存),需寫入 Swap 或文件后才能回收

其他關鍵參數

參數描述

Anonymous

4,088 kB

匿名內存總量

(無法關聯文件的內存,如?malloc?分配的內存)

Swap

0 kB

已換出到 Swap 分區的內存量,此處為 0 表示未啟用 Swap 或內存充足

Locked

0 kB

通過?mlock?鎖定的內存(不可被換出),常用于實時性要求高的場景

Referenced

12,692 kB

最近被訪問過的內存頁,反映當前活躍內存


這是兩個 OOM 內存殺手相關的,這里不多講,在之后的博客中會和小伙伴分享

┌──[root@liruilongs.github.io]-[/usr/lib/systemd/system]?

└─$cat? /proc/1/oom_score

0

┌──[root@liruilongs.github.io]-[/usr/lib/systemd/system]?

└─$cat? /proc/1/oom_score_adj?

0

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/pingmian/82540.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/82540.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/82540.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

決策樹 GBDT XGBoost LightGBM

一、決策樹 1. 決策樹有一個很強的假設&#xff1a; 信息是可分的&#xff0c;否則無法進行特征分支 2. 決策樹的種類&#xff1a; 2. ID3決策樹&#xff1a; ID3決策樹的數劃分標準是信息增益&#xff1a; 信息增益衡量的是通過某個特征進行數據劃分前后熵的變化量。但是&…

java基礎學習(十四)

文章目錄 4-1 面向過程與面向對象4-2 Java語言的基本元素&#xff1a;類和對象面向對象的思想概述 4-3 對象的創建和使用內存解析匿名對象 4-1 面向過程與面向對象 面向過程(POP) 與 面向對象(OOP) 二者都是一種思想&#xff0c;面向對象是相對于面向過程而言的。面向過程&…

TCP 三次握手,第三次握手報文丟失會發生什么?

文章目錄 RTO(Retransmission Timeout)注意 客戶端收到服務端的 SYNACK 報文后&#xff0c;會回給服務端一個 ACK 報文&#xff0c;之后處于 ESTABLISHED 狀態 因為第三次握手的 ACK 是對第二次握手中 SYN 的確認報文&#xff0c;如果第三次握手報文丟失了&#xff0c;服務端就…

deepseek告訴您http與https有何區別?

有用戶經常問什么是Http , 什么是Https &#xff1f; 兩者有什么區別&#xff0c;下面為大家介紹一下兩者的區別 一、什么是HTTP HTTP是一種無狀態的應用層協議&#xff0c;用于在客戶端瀏覽器和服務器之間傳輸網頁信息&#xff0c;默認使用80端口 二、HTTP協議的特點 HTTP協議…

openresty如何禁止海外ip訪問

前幾天&#xff0c;我有一個徒弟問我&#xff0c;如何禁止海外ip訪問他的網站系統&#xff1f;操作系統采用的是centos7.9&#xff0c;發布服務采用的是openresty。通過日志他發現&#xff0c;有很多類似以下數據 {"host":"172.30.7.95","clientip&q…

理解 Redis 事務-20 (MULTI、EXEC、DISCARD)

理解 Redis 事務&#xff1a;MULTI、EXEC、DISCARD Redis 事務允許你將一組命令作為一個單一的原子操作來執行。這意味著事務中的所有命令要么全部執行&#xff0c;要么全部不執行。這對于在需要一起執行多個操作時保持數據完整性至關重要。本課程將涵蓋 Redis 事務的基礎知識…

Milvus分區-分片-段結構詳解與最佳實踐

導讀&#xff1a;在構建大規模向量數據庫應用時&#xff0c;數據組織架構的設計往往決定了系統的性能上限。Milvus作為主流向量數據庫&#xff0c;其獨特的三層架構設計——分區、分片、段&#xff0c;為海量向量數據的高效存儲和檢索提供了堅實基礎。 本文通過圖書館管理系統的…

Kettle 遠程mysql 表導入到 hadoop hive

kettle 遠程mysql 表導入到 hadoop hive &#xff08;教學用 &#xff09; 文章目錄 kettle 遠程mysql 表導入到 hadoop hive創建 對象 執行 SQL 語句 -mysql 導出 CSV格式CSV 文件遠程上傳到 HDFS運行 SSH 命令遠程登錄 run SSH 并執行 hadoop fs -put 建表和加載數據總結 創…

Linux輸出命令——echo解析

摘要 全面解析Linux echo命令核心功能&#xff0c;涵蓋文本輸出、變量解析、格式控制及高級技巧&#xff0c;助力提升Shell腳本開發與終端操作效率。 一、核心功能與定位 作為Shell腳本開發的基礎工具&#xff0c;echo命令承擔著信息輸出與數據傳遞的重要角色。其主要功能包…

Windows系統下 NVM 安裝 Node.js 及版本切換實戰指南

以下是 Windows 11 系統下使用 NVM 安裝 Node.js 并實現版本自由切換的詳細步驟&#xff1a; 一、安裝 NVM&#xff08;Node Version Manager&#xff09; 1. 卸載已有 Node.js 如果已安裝 Node.js&#xff0c;請先卸載&#xff1a; 控制面板 ? 程序與功能 ? 找到 Node.js…

【leetcode】977. 有序數組的平方

有序數組的平方 題目代碼1. 使用sorted2. 雙指針 題目 977. 有序數組的平方 給你一個按 非遞減順序 排序的整數數組 nums&#xff0c;返回 每個數字的平方 組成的新數組&#xff0c;要求也按 非遞減順序 排序。 示例 1&#xff1a; 輸入&#xff1a;nums [-4,-1,0,3,10] 輸…

Obsidian 數據可視化深度實踐:用 DataviewJS 與 Charts 插件構建智能日報系統

Obsidian 數據可視化深度實踐&#xff1a;用 DataviewJS 與 Charts 插件構建智能日報系統 一、核心架構解析 本系統基于 Obsidian 的 DataviewJS 和 Charts 插件&#xff0c;實現日報數據的自動采集、可視化分析及智能回溯功能&#xff08;系統架構原理見&#xff09;。其技術…

深入解析Spring Boot與Kafka集成:構建高效消息驅動應用

深入解析Spring Boot與Kafka集成&#xff1a;構建高效消息驅動應用 引言 在現代分布式系統中&#xff0c;消息隊列是實現異步通信和解耦的關鍵技術之一。Apache Kafka作為一款高性能、分布式的消息隊列系統&#xff0c;廣泛應用于大數據和實時數據處理場景。本文將詳細介紹如…

Rust 學習筆記:關于生命周期的練習題

Rust 學習筆記&#xff1a;關于生命周期的練習題 Rust 學習筆記&#xff1a;關于生命周期的練習題生命周期旨在防止哪種編程錯誤&#xff1f;以下代碼能否通過編譯&#xff1f;若能&#xff0c;輸出是&#xff1f;如果一個引用的生命周期是 static&#xff0c;這意味著什么&…

word解決不同文檔同樣的字體段落設置下看起來行距不同的問題

問題&#xff1a; 有時候我們照著模板修改文檔格式&#xff0c;明明字體和段落設置一模一樣&#xff0c;但是看起來行距不一樣。 解決辦法&#xff1a; 一般照著模板修改文檔內容&#xff0c;要注意以下幾點&#xff0c;如果以下幾點與模板設置相同時就可解決上述問題 1、紙…

Jenkins實踐(9):配置“構建歷史的顯示名稱,加上包名等信息“

Jenkins實踐(9):配置“構建歷史的顯示名稱,加上包名等信息“ 版本:Jenkins 4.262.2 需求:想要在構建歷史中展示,本次運行的是哪個版本或哪個包 操作步驟: 1、先安裝插件Build Name and Description Setter 2、Set Build Name 3、構建歷史處查看展示 插件特性說明 安裝依賴…

matIo庫及.mat數據格式介紹

一.概述 1..mat數據格式 &#xff08;1&#xff09;.mat 是 MATLAB 軟件的標準二進制數據存儲格式&#xff0c;用于保存變量、矩陣、數組、結構體等數據類型。其名稱源于 “MATLAB Data” 的縮寫&#xff0c;最初設計為高效存儲和加載 MATLAB 環境中的數據&#xff0c;后來逐…

企業級調度器LVS (面試版)

1. 什么是 LVS?有什么作?? LVS ( Linux Virtual Server )是?個基于 Linux 內核實現的?性能、可擴展和可靠的負載均衡。它將多個服務器組成?個?可?、?性能和?可靠的虛擬服務器集群,通過將客戶端的請求轉發到不同的后端服務器,實現負載均衡和?可?性。 2.什么是 …

用python制作一個簡易的聊天室軟件

文章目錄 效果圖python源碼使用說明效果圖 只需要一百多行的python代碼,就能制作一個簡易的聊天室軟件。效果如下: 操作說明: 1、先運行server.py啟動服務器; 2、每運行一次client.py可以創建一個聊天用戶(需要輸入用戶昵稱); 3、輸入對方的昵稱即可與其聊天,輸入“a…

Android13 開機時間優化

前言 在實際應用場景中&#xff0c;特定領域對 Android 系統的啟動時間有著極為嚴苛的要求&#xff0c;車載領域便是典型代表。想象一下&#xff0c;當車輛已經行駛出數公里之遙&#xff0c;車內的信息娛樂系統&#xff08;IVI&#xff09;卻仍未完成啟動&#xff0c;這無疑會…