HP-UX top 輸出中實存(real memory)/虛存(virtual memory)資料解釋

stevens0102發表於2010-11-04
top 是 Unix/Linux 中一個非常直觀的效能觀察工具,它能把與系統負載、CPU、記憶體、程式、I/O 相關的效能資料展示在一個畫面中。在 AIX 中 top 有另一個名字叫 topas,今天想談談 HP-UX 中的 top,在 HP-UX 中 top 輸出最讓人困惑的是關於記憶體的一組資料,下面是 HP-UX 中一個 top 輸出:

JHDB0100@oracle[/var/adm/syslog] top
System: JHDB0100                                      Wed Nov  3 10:19:48 2010
Load averages: 0.37, 0.40, 0.40
341 processes: 317 sleeping, 23 running, 1 zombie
Cpu states:
CPU   LOAD   USER   NICE    SYS   IDLE  BLOCK  SWAIT   INTR   SSYS
 0    0.36  25.7%   0.0%   2.4%  71.9%   0.0%   0.0%   0.0%   0.0%
 1    0.39  41.9%   0.0%   1.8%  56.3%   0.0%   0.0%   0.0%   0.0%
 2    0.36  32.3%   0.0%   2.0%  65.7%   0.0%   0.0%   0.0%   0.0%
 3    0.38  42.9%   0.0%   2.0%  55.1%   0.0%   0.0%   0.0%   0.0%
---   ----  -----  -----  -----  -----  -----  -----  -----  -----
avg   0.37  35.7%   0.0%   2.2%  62.2%   0.0%   0.0%   0.0%   0.0%

Memory: 3823384K (1165440K) real, 4413348K (1410548K) virtual, 3702400K free  Pa
ge# 1/38

CPU TTY  PID USERNAME PRI NI   SIZE    RES STATE    TIME %WCPU  %CPU COMMAND
 0   ?  4630 oracle   240 20  3942M  8320K run   5542:35 53.65 53.56 oracleodsbp
 0   ?  4650 oracle   154 20  3942M  8512K sleep 6003:43 16.88 16.85 oracleodsbp
 1   ?  4626 oracle   212 20  3942M  8384K run   5727:08 13.76 13.73 oracleodsbp
 3   ? 26787 oracle   154 20  3962M 28672K sleep    1:20  6.55  6.54 oracleodsbp
 3   ? 28452 oracle   183 20  3962M 28672K run      0:04  6.55  ***3 oracleodsbp
 3   ? 27675 oracle   154 20  3962M 28672K sleep    0:43  6.38  6.37 oracleodsbp
 2   ? 28044 oracle   154 20  3962M 28672K sleep    0:23  6.36  6.35 oracleodsbp
 2   ? 23047 patrol   154 20  3987M 52288K sleep 1306:05  6.31  6.29 oracleodsb
.................

這是臺資料庫伺服器,工作負荷不算很重,load 值很低(<=0.40),總共有 341 個程式,其中與 oracle 相關的程式有 142 個,在 Memory 節有 5 個數字,反映的是實存使用量(real memory usage)、虛存使用量(virtual memory usage)和剩餘自由記憶體量(the amount of free memory),前兩個量都包含一個帶括號的資料,表示的是活動(active)實存使用量或活動(active)虛存使用量, 在 一文中對 active 的解釋是特指可執行程式(runnable processes)。Memory 節的數字單位是頁(1 頁是 4096 位元組),在 HP-UX 的 top 輸出中,你沒法知道系統配置的實體記憶體總量,而 AIX 和 Linux 的 top 輸出中是可以看到這個資料的,你問我為什麼?我也不知道,HP 完全可以把這個資料放到 top 中。獲取系統實體記憶體總量值最簡便的方法是看 syslog 檔案,它不需要超級使用者許可權(dmesg 命令需要 root 許可權)。

JHDB0100@oracle[/var/adm/syslog]pwd
/var/adm/syslog
JHDB0100@oracle[/var/adm/syslog]cat syslog.log | grep -i physical
Jul 23 20:34:25 JHDB0100 vmunix:     physical page size = 4096 bytes, logical page size = 4096 bytes
Jul 23 20:34:25 JHDB0100 vmunix:     Physical: 16775168 Kbytes, lockable: 12067576 Kbytes, available: 13882964 Kbytes
JHDB0100@oracle[/var/adm/syslog]

透過這個 syslog 檔案,我們就知道這是一個 16GB 的系統,注意 available 記憶體數,physical 減去 available 得到的差額就是系統啟動後核心程式碼(kernel code)及核心資料結構(kernel data structures)佔用的記憶體量,我們的示例中核心使用了 2892204KB 記憶體。

top 輸出中實存使用總量(total of used real memory)包括核心佔用部分和全部使用者程式佔用部分,不包括共享記憶體部分,仍以前面資料為例,用 top 中實存佔用總量 3823384KB,減去核心佔用的 2892204KB, 使用者程式大概佔用 1GB 的記憶體空間,如何進行印證呢?一種方法是利用 top 輸出中程式的 RES 欄位值,RES 表示一個程式放到記憶體中的全部私有區(private regions)大小,私有區可能包括私有資料區、堆疊區,示例中的  oracle 程式有多個例項(呵呵,這裡不是指資料庫例項,指的是作業系統同名程式),其執行映像是共享的,不在私有區,利用 top -n 及 -f 選項得到全部程式的 RES 資料,全部加起來是 2GB,不要太在意資料的精確性,2GB 裡面可能還是存在重複計算的問題;另一種方法是利用 ps 的 SZ 欄位值,SZ 包括了放到記憶體中的執行映像、資料及堆疊空間,當系統中同一程式存在大量例項時(譬如類似 oracle 那樣的程式),累加結果會非常離譜,可用如下命令計算全部程式的 SZ 和:

JHDB0100@oracle[/home/db/oracle]UNIX95=1 ps -eo sz,pid,args | sort -nr | awk '{ print $1 }' | awk '{ total += $1} END { print total }'

SZ 數字單位是頁(4096位元組),前面 341 個程式用 ps 算的結果是 16GB, 嚇一跳吧,這資料還有沒有意義啊,這裡面重復統計的數量驚人,一個 oracle 程式的 SZ 值一般有 29000 頁(即 110 MB),估計這裡面只有 20MB 左右是私有的,其它都是共享的,16GB - (140 X 100MB)= 2GB(oracle 程式數是 140 個), 也與 top 計算的相當。這裡我們都是用常規工具(ps、top 等)做些近似計算,藉此我們對 top 中實存使用總量有點印象了,那麼接下來要問的就是活動實存使用量怎麼得來的?我們看到可執行程式(runnable processes)有 23 個,1165440KB 活動實存用量就是這 23 個活動程式所佔用記憶體與活動核心程式碼所佔用記憶體之和。

好了該談談 memory 節與虛存有關的兩個數字了,即虛存使用總量和活動虛存用量,Unix/Linux 都透過虛存技術管理記憶體,這裡不說虛存技術的好處了,先交代兩點,一是虛存使用總量一定大於等於實存使用總量,活動虛存用量一定大於等於活動實存用量;二 是虛存大於實存的那一部分不要認為就一定分配到了 swap 上,現代作業系統都有共享庫動態載入機制,許多庫檔案在虛存上有空間定義,但未必放到了記憶體中,此外有些程式透過 malloc 分配了空間,但程式執行期間又沒有用到它,它就只在虛存中存在。

活動虛存用量與 vmstat 輸出中的 avm 值相當,可互相參照,看下面 vmstat 輸出:

JHDB0100@oracle[/home/db/oracle]vmstat 3 3
         procs           memory                   page                              faults       cpu
    r     b     w      avm    free   re   at    pi   po    fr   de    sr     in     sy    cs  us sy id
    3     1     0   374018  946742  275    5     0    0     0    0     0   3088  54217  1761  30  3 66
    3     1     0   374018  946656   10    0     0    0     0    0     0   2549  45126  1210  26  2 72
    3     1     0   374018  946686   11    0     0    0     0    0     0   2529  46178  1222  25  2 73
JHDB0100@oracle[/home/db/oracle]

avm 欄位資料單位是頁(4KB)。avm 值與活動虛存用量大體相當,這實際上是一個經驗觀察的結果,雖然兩者說的都是虛存的事,但定義上是有差別的,根據 Eric Herberholz 的交代,活動虛存用量指的是可執行程式對記憶體的總需求量,不含睡眠或暫停的程式(Total memory for runnable processes, as opposed to sleeping or stopped processes.),而 avm,[ ] 中是這樣描述的: avm stands for active virtual memory. It takes looking at the vmstat source code to determine that avm is the sum of text, data, and stack pages in use for all processes, not including shared library or shared memory pages!

vmstat 中 avm 包括了全部程式的執行映像、資料區及堆疊區,但不包括共享庫或共享記憶體部分。avm 不僅僅針對活動程式,睡眠程式或者暫停程式都在其統計範圍內。這是個有趣的問題,top 的活動虛存用量與 vmstat 的 avm 來了個殊途同歸,這個現象我也無法解釋,因為我沒有讀 top 和 vmstat 的原始碼。

memory 節剩下的最後一項資料是自由記憶體量,示例中是 3702400KB, 這與 vmstat 的 free 欄位是對應的。

有了上面關於 top 輸出中 memory 部分稍微理性的知識,我們就能讓 top 在記憶體分析方面發揮些作用。

我們來看看這個 16GB 的資料庫伺服器記憶體是如何使用的?

先看下交換空間使用情況

JHDB0100@oracle[/home/db/oracle]swapinfo -t
             Kb      Kb      Kb   PCT  START/      Kb
TYPE      AVAIL    USED    FREE  USED   LIMIT RESERVE  PRI  NAME
dev     8388608       0 8388608    0%       0       -    1  /dev/vg00/lvol2
reserve       - 5960172 -5960172
memory  12091508 8622892 3468616   71%
total   20480116 14583064 5897052   71%       -       0    -

很好,沒有使用交換空間。我們已經知道自由空間有 3.7GB 的樣子,Cache 用了多少呢?Cache 在 top 及 vmstat 中都看不到,用下面的命令:

SADB3900@oracle[/home/db/oracle]sysdef | grep buf
bufpages                1258137          -          0-           Pages   -

bufpages 單位是頁(4KB),算一下 Cache 用掉了 5GB 的空間,16GB - 3.7GB - 5GB = 7.3GB,剩下的 7.3GB 空間花在哪裡?這是個 Oracle 資料庫,執行以下命令:

JHDB0100@oracle[/home/db/oracle]sqlplus "/as sysdba"
.........
Connected to:
Oracle Database 10g Enterprise Edition Release 10.2.0.3.0 - 64bit Production
With the Partitioning, OLAP and Data Mining options

SQL> show sga

Total System Global Area 3875536896 bytes
Fixed Size                  2062952 bytes
Variable Size             436209048 bytes
Database Buffers         3422552064 bytes
Redo Buffers               14712832 bytes
SQL>

知道 SGA 用掉 3.8GB 的空間(共享記憶體部分),再剩下的就是 top 輸出中顯示的實存使用總量(3823384K),計算結果有點出入很正常,基本上都對上了。一個 16GB 的系統,如果有個 2GB、幾 GB 的空間對不上,你可得好好查查。

我們再來看看 lunar 的那篇文章“一次異常記憶體消耗問題的診斷及解決 ”  ,這是一篇經典的記憶體效能分析文章,仔細閱讀,確實頗有收穫,不過我想做些補充。這是一臺 16GB 的 RAC 資料庫系統,作業系統是 HP-UX 11.11,透過 top 或者 vmstat 我們都能看到系統只剩 200MB 的自由記憶體了,但是 200MB 未必就不能工作,這要結合你的應用進行觀察,在 vmstat 輸出中我們看到 pi 值平均在 30 以上,re 值也超過 100,頁活動非常頻繁,pi 表示的是交換出去的頁又被調回來;再看交換空間的使用情況(swapinfo),32GB 的交換空間(/dev/vg00/lvol2)中有 4GB 被用掉,不少啊,這樣看,系統記憶體確實存在問題,top 中顯示系統中有 966 個程式,其中活躍程式有 15 個,可能存在程式換進換出的問題,使用者抱怨系統慢是有原因的。現在我們做點加減法,看是否存在記憶體丟失或使用異常的問題,這是個 Oracle 資料庫伺服器,SGA 用掉了 7.3GB, 自由記憶體有 200MB, 用 16GB 減去這兩部分,還剩 8.5GB 空間,這 8.5 GB 空間會由核心程式碼與核心資料結構、全部程式的常駐記憶體段(含 text、data、stack)和檔案系統 Cache 構成,根據 top ,我們發現實存使用總量有 14GB,太大了,900多個程式加核心佔用不可能用到 14GB,14GB 還不含 Cache 和共享記憶體部分,說不定 SGA 的一部分都到了交換區上,lunar 文中未提到 Cache 值,因 Cache 是動態調整的,記憶體這麼吃緊,估計 Cache 也挪作他用了,頂多剩下幾十、上百兆。900多程式加核心頂多用到 7GB 左右,那還有 7GB 被誰用了,肯定不會是核心,可以用 ps 查查(看 SZ 欄位)哪個程式用了上 GB 的記憶體,lunar 是透過 ipcs 和 shminfo 命令找到這個程式的,順便說一下,用 ipcs 看到的那個異常的 6.2GB 的共享記憶體段是不正常的,它已經變成了私有記憶體段。

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/23488160/viewspace-677762/,如需轉載,請註明出處,否則將追究法律責任。

相關文章