メモリ情報の詳細を探る


表1.ポイントと内容

No ポイント コマンド、オプション等 内容
@ IPCの状態は? ipcs -a メッセージキュー:CBYTESとQNUMを確認
共有メモリ:SEGSZを確認
セマフォ:NSEMSを確認
A プロセスのメモリ使用量の調べ方は? ps -efly RSSとSZの項目を確認
accton filename プロセスアカウンティングの起動
accton プロセスアカウンティングの停止
acctcom -f -m -t filename MEAN SIZE(K)を確認
B ISM型共有メモリとスワップ領域の関係は? swap -s availableのサイズを確認
C メモリ構成要素はどうなっているのか? adb -k (UNIXサイズを求める) physinstalled - physmem (ページ)
sar -k (カーネルメモリサイズ) sml_mem/alloc/fail
lg_mem/alloc/fail
ovsz_alloc
crash kmastat カーネルメモリの詳細
adb -k (ページ構造体配列) physmem × 64バイト
sar -r (空きメモリページ) freemem ≒ lotsfree
adb -k (physmem) physmem ÷ 64 (ページ) = lotsfree
df -k (ディスクバッファキャッシュ) ファイルシステム使用量の1〜2パーセント
pmap -x PID (プロセスのセグメントマップ) Dを参照してください。
D ユーザメモリはどうなっているのか? Address=0x00010000とread/exec テキストセグメント
Address=0xxxxxxxとread/write/exec データセグメント
Address=Fxxxxxxと[ heap ] ヒープセグメント
Address=Fxxxxxxと[ stack ] スタックセグメント
Mapped Fileに[ shmid=0x5 ]のように表示 プライベート(親子)型共有メモリ
Mapped Fileに[ ism shmid=0x281 ]のように表示 ISM型共有メモリ
E ワーキングセットはどう計測するのか? pmap -xとメモリsweep outのプログラム 呼び戻されるバイト数を確認


@IPCの状態は?

ipcsコマンド-aオプションはSystem V IPC(プロセス間通信)の状態を表示します。メモリサイズに影響する項目はメッセージキューのQNUMとQBYTES、共有メモリのSEGSZ、およびセマフォのNSEMSです。図1の例ではメッセージキューはありません。共有メモリはORACLEのSGAで約386メガバイトが確保されていることがわかります。セマフォは154個をORACLEが使用しています。なお、編集の都合上、一部表示内容を変更しています。

# ipcs -a <CR>
IPC status from < rnning system > as of The Jul 8 17:03:17 JST 2004
T ID KEY MODE OWNER GROUP CREATOR CGROUP CBYTES QNUM
QBYTES
LSPID
LRPID
STIME RTIME CTIME
Message Queues:
q 0 0x2e781d5 -rw-r-r-- root root root root 0 0  40 96 0 00:00:00 00:00:00 10:23:55
q 1 0x2e781d2 -Rr-w-w- root root root root 0 0  40 96 0 00:00:00 00:00:00 10:23:55
q 2 0x12f8 -Rrw-r-r- root root root root 0 0  40 96 0 00:00:00 00:00:00 10:24:01
T ID KEY MODE OWNER GROUP CREATOR CGROUP NATTCH SEGSZ CPID LPID ATIME DTIME CTIME
Shared Memory:
m 0 0x50000c0d -rw-r-r-- root root root root 1 4 265 265 10:23:52 10:23:52 10:23:52
m 129 0x5766d550 -rw-r---- oracle dba oracle dba 10 386424832 443 475 10:32:31 10:32:57 10:32:22
T ID KEY MODE OWNER GROUP CREATOR CGROUP NSEMS OTIME CTIME
Semaphores:
s 19608 0x1ff2e530 -ra-r---- oracle dba oracle dba 154 17:01:48 10:32:22
#

図1.ipcsコマンド-aオプションの出力


Aプロセスのメモリ使用量の調べ方は?

メモリに常駐しているプロセスのメモリ使用量は、psコマンド-eflyオプションで確認します。RSSは常駐しているサイズ、SZは実サイズです。単位はページで、通常1ページ8192バイトです。1ページのサイズはpagesizeコマンドで確認してください。RSSは表示が6桁におよぶと、前のフィールドNIと値がくっついてしまうようです。ご注意ください。なお、pmapコマンド-xオプションで調査する方が詳細なセグメント情報を知ることが出来ます。Dユーザメモリはどうなっているのか?をご覧ください。

# ps -efly <CR>
S UID PID PPID C PRI NI RSS SZ WCHAN STIME TTY TIME CMD
T root 0 0 0 0 SY 0 0 13:10:20 ? 0:01 sched
S root 1 0 0 41 20 384 816 ? 13:10:21 ? 0:00 /etc/init -
S root 2 0 0 0 SY 0 0 ? 13:10:21 ? 0:00 pageout
S root 3 0 0 0 SY 0 0 ? 13:10:21 ? 0:42 fsflush
S root 73 1 0 50 20 1984 3208 ? 13:10:35 ? 0:00 devfsadmd
S root 392 1 0 45 20 1136 1784 ? 13:10:54 console 0:00 /usr/lib/saf/ttymon -g -h -p act061
S root 299 298 0 59 20 720 1704 ? 13:10:48 ? 0:00 /usr/sadm/lib/smc/bin/smcboot
S root 397 375 0 40 20 70168 28368 ? 13:10:55 ? 0:01 /usr/openwin/bin/Xsun :0 -nobanner
S root 415 373 0 41 20 2072 2568 ? 13:10:58 ? 0:03 mibiisa -r -p 32793
S oracle 445 1 0 40 20 387264 425600 ? 13:17:59 ? 0:00 ora_pmon_ora900
S oracle 447 1 0 40 20 389040 427760 ? 13:17:59 ? 0:00 ora_dbw0_ora900
S oracle 449 1 0 40 20 387912 430656 ? 13:17:59 ? 0:00 ora_lgwr_ora900
S oracle 451 1 1 41 20 390960 426432 ? 13:17:59 ? 1:03 ora_ckpt_ora900
S oracle 453 1 0 41 20 390304 425104 ? 13:17:59 ? 0:01 ora_smon_ora900
S oracle 455 1 0 41 20 389664 425032 ? 13:17:59 ? 0:00 ora_reco_ora900
S oracle 457 1 0 40 20 389728 425032 ? 13:17:59 ? 0:00 ora_cjq0_ora900
S oracle 459 1 0 40 20 386560 425504 ? 13:17:59 ? 0:00 ora_s000_ora900
S oracle 461 1 0 40 20 386400 425360 ? 13:17:59 ? 0:00 ora_d000_ora900
S oracle 463 1 0 40 20 386408 425360 ? 13:17:59 ? 0:00 ora_d001_ora900
S oracle 465 1 0 40 20 386408 425360 ? 13:17:59 ? 0:00 ora_d002_ora900
S root 515 202 0 45 20 1360 1808 ? 15:14:02 ? 0:00 in.telnetd
S nuruki 517 515 0 59 20 1144 2040 ? 15:14:02 pts/5 0:00 -sh
S root 526 517 0 51 20 320 320 ? 15:14:24 pts/5 0:00 -sh
#

図2.1 psコマンド-eflyオプションの出力(抜粋)

メモリに常駐しない、いわゆるただちに終了してしまうコマンドは、プロセスアカウントを採取してメモリ使用量を確認します。但し、プロセスアカウントが表示するMEAN SIZE(K)は、プログラムの実行後にmallocで拡張されたメモリ量は含まないことに注意してください(異常終了したプロセスは反映される場合もあるようです)。

# /usr/lib/acct/accton pacct_info <CR>
# ps <CR>
PID TTY  TIME CMD
611 pts/5 0.00 ps
526 pts/5 0.00 sh
# /usr/lib/acct/accton <CR>
# acctcom -f -m -t pacct_info <CR>
COMMAND START END REAL CPU (SECS) MEAN
NAME USER TTYNAME TIME TIME (SECS) SYS USER SIZE(K) F STAT
#accton root pts/5 18:41:24 18:41:24 0.05 0.00 0.00 320.00 42 0
ps root pts/5 18:41:29 18:41:29 0.03 0.03 0.00 877.33 42 0

図2.2 プロセスアカウンティングによるプロセスサイズの調査


BISM型共有メモリとスワップ領域の関係は?

ISM型共有メモリは、領域をメモリに確保する時、ページアウトされないようロックします。ところが、ページング対象ではないのにもかかわらず、スワップ領域は確保するという変わりだねです。この振る舞いをswapコマンド-sオプションで確認してみました。

# swap -s <CR>
total: 33816k bytes allocated + 6720k reserved = 40536k used, 1314272k available ←初期値です。
#
【この間にSGAサイズを設定してORACLEを起動します。】
# swap -s <CR>
total: 425728k bytes allocated + 14720k reserved = 440448k used, 913688k available ←380メガバイトSGAの場合。
#
【この間にSGAサイズを変更してORACLEを再起動します。】
# swap -s <CR>
total: 924656k bytes allocated + 115720k reserved = 1040376k used, 307384k available ←900メガバイトSGAの場合。
#

図3.ISM型共有メモリの確保とスワップ領域の関係

このように、ORACLEで大きなSGAを構成したり、WebLogicのISMオプションでJavaヒープを構成したりするような場合、スワップサイズの決定に注意が必要です。


Cメモリ構成要素はどうなっているのか?

メモリ構成は図4.1のように大きく6つの要素に分けられます。

要素の概要 概念図
(1)カーネル
UNIXそのものです。

(2)カーネルメモリ
カーネルメモリは3種類の領域で管理されています。スモールカーネルリとラージカーネルメモリはプールされ、再利用されます。オーバーサイズメモリは割り当て・解放されます。

(3)ページ構造体配列
概念図には記述していませんが、全メモリページを管理するためのページ構造体配列があります。ページ構造体は1ページあたり64バイトです。

(4)フリーメモリ
物理メモリの1/64が目安です。

(5)ユーザプロセス
実行中のプロセスが占めるメモリです。Dユーザメモリはどうなっているのか?を参照してください。

(6)ディスクバッファキャッシュ
ファイルシステムをアクセスする場合に使用されるメモリです。

【備考】必ずしもこの順番にメモリに存在する訳ではありません。あくまでも概念としてご覧ください。

図4.1 メモリの構成要素

続いて、各要素の求め方を解説します。

(1)カーネルサイズの求め方

カーネルのサイズは、構成メモリから物理メモリを引いて求めます。構成メモリはphysinstalled、物理メモリはphysmemと呼ばれるカーネル変数で示されます。次に具体的な求め方を示します。

# adb -k <CR>         ←adbコマンドを-kオプションで起動します。
physmem 1eecb
physinstalled/e <CR>    ←64ビットのカーネル変数です。"e"ファンクションで10進数表示します。
physinstalled:           32ビットの場合は"D"ファンクションを用います。
physinstalled: 131072    ←構成メモリサイズ(ページ)です。
physmem/e <CR>      ←物理メモリサイズを"e"ファンクションで10進数表示します。
physmem:             32ビットの場合は"D"ファンクションを用います。
physmem: 126667      ←物理メモリサイズ(ページ)です。
$q <CR>

# bc <CR>
131072-126667 <CR>   ←構成メモリから物理メモリサイズを引き算します。
4405
4405*8192 <CR>      ←ページをバイトにします。
36085760           ←カーネルのサイズです。
quit <CR>
#

図4.2 カーネル(UNIX)サイズを求める

(2)カーネルメモリサイズの求め方

カーネルメモリはsarコマンドの-kオプションで表示されるsml_mem、lg_mem、およびovsz_alloc項目の平均を合計して求めます。crashコマンドのkmastatファンクションはより詳細なカーネルメモリ使用状況と、カーネルセグメントの詳細を表示してくれます。

【sarコマンド-kオプションの出力】
19:49:08 sml_mem alloc fail lg_mem alloc fail ovsz_alloc fail
19:49:13 6316160 3301401 0 60063744 54458256 0 17596416 0
19:49:18 6316160 3301401 0 60063744 54458256 0 17596416 0
19:49:23 6316160 3301401 0 60063744 54458256 0 17596416 0
19:49:28 6316160 3301401 0 60063744 54458256 0 17596416 0
19:50:43 6365312 5822954 0 61071360 56794688 0 18087936 0
19:50:48 6365312 5822954 0 61071360 56794688 0 18087936 0
19:50:53 6365312 5823482 0 61071360 56794688 0 18087936 0
19:50:58 6365312 5823482 0 61071360 56794688 0 18087936 0
19:51:03 6365312 5823482 0 61071360 56794688 0 18087936 0
【備考】
Average 6336818 4614372 0 60560250 55577184 0 17832559 0
Averageを合計すると84729628になります。

【備考】sarコマンドの-kオプションは最終行のAverage項目を表示しません。
この例は計算して平均値を出したものです。

図4.3 カーネルメモリサイズの求め方

crashコマンドkmastatファンクションの出力例を図4.4に示します(抜粋)。

# crash <CR>
> kmastat <CR>
cache buf buf buf memory alloc alloc
name size in use total in use succeed fail
------------------------- ------ ------ ------ --------- --------- -----
kmem_magazine_1 16 218 508 8192 218 0
kmem_slab_cache 56 2114 2159 139264 2114 0
kmem_bufctl_cache 32 8145 8382 270336 8145 0
kmem_va_8192 8192 3305 3328 27262976 3305 0
kmem_alloc_16384 16384 27 29 475136 1446 0
streams_mblk 64 1579 1651 106496 10001 0
streams_dblk_8 128 12 63 8192 11836 0
streams_dblk_8040 8160 0 10 81920 656 0
sfmmu8_cache 312 8144 8164 2572288 8144 0
ism_blk_cache 200 11 16 8192 79 0
ism_ment_cache 32 11 254 8192 79 0
seg_cache 56 2404 2900 163840 285663 0
segkp_8192 8192 3 16 131072 4 0
segkp_40960 40960 0 66 2883584 4680 0
thread_cache 680 210 242 180224 9377 0
dnlc_space_cache 24 150 339 8192 197 0
file_cache 56 460 580 32768 89893 0
stream_head_cache 392 192 220 90112 11215 0
queue_cache 608 543 572 360448 13966 0
syncq_cache 160 27 50 8192 193 0
qband_cache 64 2 127 8192 2 0
anon_cache 48 54360 55770 2703360 393722 0
anonmap_cache 56 2057 2610 147456 146620 0
segvn_cache 88 2387 2852 253952 271174 0
ufs_inode_cache 472 6050 6052 2916352 6440 0
sock_cache 432 63 72 32768 516 0
sock_unix_cache 432 5 18 8192 5 0
process_cache 2704 72 93 253952 9043 0
fnode_cache 264 6 28 8192 28 0
pipe_cache 496 13 32 16384 4918 0
pty_map 48 4 169 8192 4 0
------------------------- ------ ------ ------ --------- --------- -----
Total [kmem_internal] 966656 15168 0
Total [kmem_va] 28049408 3339 0
Total [kmem_default] 27672576 2348284 0
Total [id32] 8192 26 0
Total [segkp] 10747904 5101 0
Total [ip_minor] 128 752 0
------------------------- ------ ------ ------ --------- --------- -----
arena memory memory memory alloc alloc
name in use total import succeed fail
------------------------- --------- ---------- --------- --------- ----- -----
heap 49537024 68719476736 0 2315 0
vmem_seg 598016 598016 598016 73 0
vmem_vmem 105952 114104 57344 49 0
kmem_internal 1138688 1138688 1138688 153 0
kmem_cache 158400 172032 172032 237 0
kmem_log 65792 73728 73728 6 0
kmem_oversize 17837140 18087936 18087936 1578 0
mod_sysfile 775 8192 8192 27 0
kmem_va 28049408 28049408 28049408 107 0
kmem_default 27672576 27672576 27672576 3339 0
little_endian 80960 90112 90112 119 0
bp_map 0 0 0 0 0
ksyms 830076 876544 876544 283 0
heap32 2015232 67108864 0 134 0
id32 8192 8192 8192 1 0
module_text 3243192 3383296 1286144 278 0
module_data 701360 901120 638976 364 0
promplat 0 0 0 24 0
segkp 10747904 2075312128 0 82 0
taskid_space 5 999998 0 5 0
pcisch0_dvma 22429696 1040187392 0 6141 0
pcisch1_dvma 0 1040187392 0 475 0
ip_minor 128 262142 0 2 0
tcp_minor 0 262142 0 0 0
ar_minor 0 262142 0 0 0
udp_minor 0 262142 0 0 0
ptms_minor 4 16 0 4 0
semaphore 154 1024 0 8 0
------------------------- --------- ---------- --------- --------- ----- -----
>q <CR>
#

図4.4 crashコマンドkmastatファンクションの出力(抜粋)

(3)ページ構造体配列のサイズの求め方

ページ構造体は1ページあたり64バイトです。構成メモリのページ数にこれを掛け算すると構造体配列のサイズがわかります。

# adb -k <CR>
physmem 1eecb
physinstalled/e <CR>    ←"e"ファンクションで、構成メモリページ数を表示します。
physinstalled:           32ビットの場合は"D"ファンクションを使用します。
physinstalled: 131072    ←構成メモリのページ数です。
$quit <CR>

# bc <CR>
131072*64 <CR>       ←64バイトを掛け算します。
8388608            ←ページ構造体配列のサイズです。
quit <CR>
#

図4.5 ページ構造体配列サイズの求め方

(4)フリーメモリの求め方

フリーメモリは、物理メモリの1/64が目安です。lotsfree、またはcachefreeカーネル変数を確認します。

# adb -k <CR>
physmem 1eecb
lotsfree/e <CR>      ←"e"ファンクションでページングしきい値を表示します。これがフリーメモリの目安になります。
lotsfree:             32ビットの場合は"D"ファンクションで表示します。
lotsfree: 1955        ←ページングしきい値のページ数です。
cachefree/e <CR>     ←念のため、cachefreeも表示してみます。
cachefree:
cachefree: 1955      ←lotsfreeと同じ値です。
$q <CR>

# bc <CR>
1955*8192 <CR>     ←ページサイズを掛け算します。
16015360          ←フリーメモリの目安です。
quit <CR>
#

図4.6 フリーメモリの求め方

(5)ユーザメモリの求め方

次のDユーザメモリはどうなっているのか?をご覧ください。

(6)ディスクバッファキャッシュの求め方

経験則として、ディスクアクセスは、ディスク全領域の10パーセントに集中すると言われています。この経験則を10/90の理論と言います。また、その10パーセントの内の10パーセントが集中的に参照されると言われています。この結果、ファイルシステム中に割当てられている全体量の1〜2パーセントにアクセスが集中すると考えると、それらがメモリ上にキャッシュされていると最も効率が良くなります。ディスク使用量を知るためには、dfコマンドの-kオプションを使います。この出力からディスクバッファキャッシュの目安を求めます。

【dfコマンド-kオプションの出力を用います】
Filesystem kbytes used avail capacity Mounted on
/dev/dsk/c1t1d0s0 6198606 2911299 3225321 48% /
/proc 0 0 0 0% /proc
fd 0 0 0 0% /dev/fd
mnttab 0 0 0 0% /etc/mnttab
swap 904976 16 904960 1% /var/run
swap 905024 64 904960 1% /tmp
/dev/dsk/c1t1d0s3 63867324 12629920 50598731 20% /opt

【used項目を合計する】
dfコマンド-kオプション出力のused部分を合計します。
単位は1024バイト(1キロバイト)です。
合計する際、swap領域は計算から除きます。
15541219 ですから、約15.5ギガバイトになります。

【1〜2パーセントを求める】
この1パーセントは約155メガバイトです。
2パーセントでは約310メガバイトと計算されます。
この値をディスクバッファキャッシュの目安として用います。

【備考】
この計算では場合によって巨大なサイズになることがあります。
この場合は構成メモリサイズ、フリーメモリなどを勘案して求めてください。
結果的に、フリーメモリを残すようにサイジングすると理想的です。

図4.7 ディスクバッファサイズの求め方

以上をまとめたものを表4.1に示します。この情報は、シナリオ番号42の出力を使用しています。

表4.1 メモリ構成要素のまとめ

No 項目 内容 ページ バイト
  PhysInstalled 構成メモリです。 131,072 1,073,741,824
  Physmem 物理メモリです。 126,667 1,037,656,064
(1) UnixSize カーネル(UNIX)サイズです。 4,405 36,085,760
(2) KernelMemory(avg) カーネルメモリの平均です。 10,342 84,721,664
(3) PageTableArraySize ページ構造体配列のサイズです。 1,024 8,388,608
(4) FreeMemory(avg) フリーメモリサイズです(実測平均値) 79,502 651,280,384
(5) UserMemory(end) ユーザメモリサイズです(実測最大値) 79,994 655,310,848
  FreeSwap(avg) フリースワップの平均サイズです。 139,105 1,139,548,160
(6) DiskBufferCache(end)1/100 ディスクバッファキャッシュの1パーセントです。 19,427 159,142,052
(6) DiskBufferCache(end)2/100 ディスクバッファキャッシュの2パーセントです。 38,853 318,284,104

表4.2は計算値を基に作成したものです。

表4.2 メモリ構成要素の計算結果

No 項目 内容 ページ バイト
(1) UnixSize カーネル(UNIX)サイズです。 4,405 36,085,760
(2) KernelMemory カーネルメモリの平均です。 10,342 84,721,664
(3) PageTableArraySize ページ構造体配列のサイズです。 1,024 8,388,608
(4) FreeMemory【備考】 フリーメモリの計算値です。 15,880 130,088,960
(5) UserMemory ユーザメモリサイズです(実測最大値) 79,994 655,310,848
(6) DiskBufferCache(end)1/100 ディスクバッファキャッシュの1パーセント推定値です。 19,427 159,142,052

 

【備考】 実際の計算結果は物理メモリの1/64、"16,015,360"バイトですが、メモリに余裕があるため、構成メモリサイズから他の構成要素をマイナスした結果をフリーメモリとして用いました。

表4.2より、ピボットグラフを作成してみました。構成メモリ内にうまく収まっていることが分かります。

図4.8 メモリの見積結果


Dユーザメモリはどうなっているのか?

基本編では、一つのプロセスをめがけてpmapコマンド-xオプションでユーザセグメントマップを出力し、その内容を確認しました。ここでは、表示された内容を掘り下げ、どのようにユーザプロセスのメモリ量を測るのかを解説します。

プロセスはテキスト、データ、およびスタックセグメントで構成されます。テキストは、プロセス本体と、使用する共用ライブラリのテキストセグメントもサイズに算入する場合があります。データセグメントは、プロセス実行時に割り当てられた共有メモリや、mallocで割り当てられたヒープセグメントが含まれることがあります。また、共用ライブラリをコールした時に使用される領域もデータセグメントと考えます。スタックセグメントはプロセスに唯一です。

図5.1 プロセスのセグメント

表5.1に、システム全体におけるユーザメモリの計算方法を、pmapコマンド-xオプションの表示項目を基に解説します。

表5.1 システム全体のユーザメモリ計算方法

No アドレス パーミッション 計算 Mapped File 内容
1 00010000 read/exec 1 プログラム名 テキストセグメントです。同じディレクトリから実行された同名のプログラムは共用されますので、1個分を計算します。他のディレクトリから実行された同名のプログラムは、別のプログラムですから、べつの1個分として計算します。
2 0xxxxxxx read/write/exec n プログラム名 コンパイル時に作成されたコンスタントや静的領域のデータセグメントです。同一プログラムでも、別プロセスの場合は領域が別になりますので、個数分、すなわち、n個を合計して計算します。
3 0xxxxxxx read/write/exec n heap プログラム実行時にmallocによって確保されたヒープセグメントです。同一プログラムでも、別プロセスの場合は領域が別になりますので個数分、すなわち、n個を合計して計算します。
4 0xxxxxxx read/write/exec n anon スワップ領域の確保を伴うプロセス固有の領域です。通常、同一プログラムで、別のプロセスの場合は領域が別になります。このため、n個を加算して計算します。
5 8xxxxxxxまたは、00000003xxxxxxxx read/write/exec/shared 1 ism shmid=0xXX ISM型共有メモリです。同一の共有メモリIDを持つ他のプロセスは、同じ領域を共有するため、1個分を計算します。
6 Fxxxxxxx read/write/exec/shared 1 shmid=0xXX 親子型共有メモリです。同一の共有メモリIDを持つ他のプロセスは、同じ領域を共有するため、1個分を計算します。
7 Fxxxxxxx read/write/exec n anon スワップ領域の確保を伴うプロセス固有の領域です。通常、同一プログラムで、別のプロセスの場合は領域が別になります。このため、n個を加算して計算します。
8 Fxxxxxxx read/exec 1 libxxxx.so.x 共用ライブラリのテキストセグメントです。同じディレクトリから実行された同名の共用ライブラリは共用されますので、1個分を計算します。別のディレクトリからロードされた同名の共用ライブラリは、別に1個分として計算します。
9 Fxxxxxxx read/write/exec n libxxxx.so.x プロセスが使用したライブラリコールによって割り当てられるヒープセグメントです。プロセス単位に割り当てられますので、n個を加算して計算します。
10 Fxxxxxxx r/w/e n stack スタックセグメントです。プロセス単位に割り当てられますので、n個を加算して計算します。
11 xxxxxxxx read/write/shared n - データセグメントとみなして、n個を加算して計算します。
12 xxxxxxxx read/shared 1 - 共有メモリとみなして、1個分を計算します。

表5.1の計算方法にあるアドレス、パーミッション、およびMapped Fileに基づいて、各セグメントのサイズを一覧にしたものです。値の単位は1024バイト(1キロバイト)です。

【pmapコマンド-xオプション出力一覧】
processname txt rtxt shs rshs shm rshm dsz rdsz hsz rhsz rsh rrsh ssz rssz pid
/bin/sh 88 88 872 856 0 0 64 64 104 104 0 0 16 16 8475
/bin/sh 88 88 872 856 0 0 64 64 104 96 0 0 16 16 9143
/bin/sh 88 88 872 856 0 0 64 64 96 96 0 0 16 16 8922
/etc/init 504 264 160 160 0 0 40 40 104 104 0 0 8 8 1
/opt/SUNWspci2/bin/sunpcid 32 32 1528 1360 0 0 176 168 184 184 0 0 16 16 387
/opt/caldera/bin/calserver 88 88 1480 1312 0 0 152 152 248 160 0 0 8 8 305
/opt/caldera/bin/keyserver 72 72 1480 1312 0 0 160 160 248 136 0 0 8 8 307
/sbin/dhcpagent 480 192 160 160 0 0 40 40 32 32 0 0 16 16 32
/usr/bin/fgd 56 56 1576 880 0 0 96 96 88 72 0 0 8 8 291
/usr/dt/bin/dtlogin 120 120 4392 3088 0 0 664 632 64 64 16 16 24 24 375
/usr/dt/bin/dtlogin 120 120 4504 3200 0 0 696 656 176 168 24 24 24 24 398
/usr/lib/ab2/dweb/sunos5/bin/dwhttpd 1048 984 7104 6000 0 0 1032 936 296 296 0 0 16 16 348
/usr/lib/ab2/dweb/sunos5/bin/dwhttpd 1048 984 7112 6008 0 0 1048 960 960 960 0 0 40 40 349
/usr/lib/autofs/automountd 128 128 2352 2080 0 0 512 496 248 192 0 0 8 8 221
/usr/lib/dmi/dmispd 64 64 2160 1888 0 0 520 464 1240 1112 0 0 8 8 384
/usr/lib/dmi/snmpXdmid 144 144 2392 2120 0 0 600 536 776 592 96 40 16 16 381
/usr/lib/im/htt 8 8 1016 992 0 0 80 80 8 8 0 0 8 8 333
/usr/lib/locale/ja/atokserver/atokmngdaemon 40 40 848 832 0 0 64 64 16 16 0 0 16 16 354
/usr/lib/locale/ja/wnn/dpkeyserv 32 32 1488 1320 0 0 152 144 24 24 0 0 16 16 323
/usr/lib/locale/ja/wnn/jserver 8 8 1464 1296 0 0 136 128 0 0 0 0 8 8 329
/usr/lib/locale/ja/wnn/jserver_m 384 384 1488 1320 0 0 168 160 232 216 8 8 16 16 330
/usr/lib/lpsched 184 184 1784 1568 0 0 232 216 1064 48 0 0 16 16 253
/usr/lib/nfs/lockd 24 24 1456 1288 0 0 152 152 256 160 0 0 16 16 218
/usr/lib/nfs/statd 40 40 1640 1464 0 0 344 336 472 344 0 0 16 16 217
/usr/lib/picl/picld 16 16 1512 1472 0 0 464 456 592 592 0 0 16 16 72
/usr/lib/power/powerd 24 24 1040 1016 0 0 256 240 104 104 8 8 8 8 266
/usr/lib/saf/sac 24 24 1488 1320 0 0 152 144 104 40 0 0 16 16 390
/usr/lib/saf/ttymon 64 64 1488 1320 0 0 152 144 64 64 0 0 16 16 391
/usr/lib/saf/ttymon 64 64 1488 1320 0 0 152 144 64 64 0 0 16 16 394
/usr/lib/sendmail 712 384 2104 1848 0 0 304 296 192 184 0 0 64 64 285
/usr/lib/snmp/snmpdx 88 88 1824 1648 0 0 272 256 144 144 0 0 16 16 373
/usr/lib/sysevent/syseventconfd 16 16 1176 1152 0 0 288 272 8 8 0 0 8 8 63
/usr/lib/sysevent/syseventd 24 24 1216 1192 0 0 440 432 32 32 104 88 16 16 61
/usr/lib/utmpd 16 16 864 848 0 0 64 64 80 56 0 0 8 8 276
/usr/openwin/bin/Xsun 1384 752 6104 4808 0 0 17152 680 3624 3488 0 0 96 96 397
/usr/openwin/bin/fbconsole 8 8 2184 1744 0 0 184 176 56 56 0 0 8 8 400
/usr/sadm/lib/smc/bin/smcboot 24 24 1488 1320 0 0 152 144 24 24 0 0 16 16 298
/usr/sadm/lib/smc/bin/smcboot 24 24 1488 1320 0 0 152 144 24 24 0 0 16 16 299
/usr/sbin/ccv 16 16 4384 3616 0 0 560 480 32 24 0 0 8 8 282
/usr/sbin/cron 40 40 1792 1616 0 0 232 224 40 40 0 0 16 16 236
/usr/sbin/cs00 120 120 1648 1448 0 0 200 200 872 336 0 0 8 8 284
/usr/sbin/cssd 16 16 848 832 0 0 56 56 16 16 0 0 16 16 281
/usr/sbin/inetd 32 32 1568 1400 0 0 176 176 648 632 0 0 16 16 210
/usr/sbin/kkcv 96 96 4384 3616 0 0 576 496 312 296 0 0 8 8 283
/usr/sbin/nscd 56 56 1864 1672 0 0 712 704 368 368 0 0 8 8 247
/usr/sbin/rpcbind 40 40 1472 1304 0 0 152 152 576 352 0 0 16 16 153
/usr/sbin/syslogd 64 64 2056 1856 0 0 1584 592 496 488 0 0 32 32 228
/usr/sbin/vold 144 144 1968 1656 0 0 400 392 168 96 800 504 16 16 317
0csh 144 144 1192 1128 0 0 144 136 104 88 0 0 24 24 1363
0csh 144 144 1192 1128 0 0 144 136 104 88 0 0 24 24 421
0sh 272 272 0 0 0 0 16 16 24 24 0 0 8 8 483
0sh 88 88 1040 1016 0 0 88 88 16 16 800 504 8 8 474
devfsadmd 64 64 2024 1744 0 0 480 456 528 528 96 72 16 16 73
dtgreet 64 64 6592 4408 0 0 832 800 680 680 240 200 144 144 414
htt_server 168 168 2640 2176 0 0 456 424 16 16 0 0 8 8 335
in.telnetd 24 24 1576 1408 0 0 176 168 16 16 0 0 16 16 1361
in.telnetd 24 24 1576 1408 0 0 176 168 16 16 0 0 16 16 419
in.telnetd 24 24 1576 1408 0 0 176 168 16 16 0 0 16 16 472
mibiisa 80 80 1784 1600 0 0 496 480 192 192 0 0 16 16 415
ora_cjq0_ora900 37176 17144 5848 4472 377368 377368 680 664 360 240 0 0 40 40 8721
ora_ckpt_ora900 37176 17144 5848 4472 377368 377368 888 872 1552 1440 0 0 40 40 8715
ora_d000_ora900 37176 17144 5848 4472 377368 377368 680 664 704 584 0 0 24 24 8725
ora_d001_ora900 37176 17144 5848 4472 377368 377368 680 664 704 584 0 0 24 24 8727
ora_d002_ora900 37176 17144 5848 4472 377368 377368 680 664 704 584 0 0 24 24 8729
ora_dbw0_ora900 37176 17144 5848 4472 377368 377368 896 880 2856 2744 0 0 24 24 8711
ora_lgwr_ora900 37176 17144 5848 4472 377368 377368 888 872 5792 1648 0 0 24 24 8713
ora_pmon_ora900 37176 17144 5848 4472 377368 377368 680 664 944 824 0 0 24 24 8709
ora_reco_ora900 37176 17144 5848 4472 377368 377368 680 664 360 240 0 0 48 48 8719
ora_s000_ora900 37176 17144 5848 4472 377368 377368 680 664 848 728 0 0 24 24 8723
ora_smon_ora900 37176 17144 5848 4472 377368 377368 680 664 384 264 0 0 64 64 8717

【項目の解説】

項目 内容
processname プロセス名です。
txt/rtxt テキストセグメントです。rtxtはメモリに常駐しているセグメントのサイズです。
shs/rshs 共用ライブラリのテキストセグメントです。rshsはメモリに常駐しているセグメントのサイズです。
shm/rshm ISM型共有メモリのセグメントです。rshmはメモリに常駐しているサイズです。通常shmの値はrshmと同じです。
dsz/rdsz データセグメントです。rdszはメモリに常駐しているサイズです。anonはこの中に含んでいます。
hsz/rhsz ヒープセグメントです。rhszはメモリに常駐しているサイズです。
rsh/rrsh プライベート型共有メモリのセグメントです。rrshはメモリに常駐しているサイズです。
ISM型共有メモリと違い、ページアウト・インされることがあります。
ssz/rssz スタックセグメントです。rsszはメモリに常駐しているサイズです。
pid プロセスIDです。

【備考】なお、Solaris2.5以前は、pmapコマンドの-xオプションで表示される項目にResident(常駐サイズ)はなく、実サイズのみが表示されます。

図5.2 pmapコマンド-xオプション出力からセグメント一覧を得る

図5.2の緑色の部分は共用されますので、同一プログラム、共用ライブラリ、および共有メモリはシステム全体で一つとして計算します。茶色の部分はプロセス毎に加算して計算します。表5.2はこの計算結果です。

表5.2 セグメントサイズの計算

ORACLE起動前 ORACLE起動後
セグメント 実サイズ 常駐サイズ 常駐率
データ 52664 31296 59
スタック 1120 1120 100
       
プライベート型共有メモリ 8 8 100
共用ライブラリ 19880 14472 73
テキスト 7472 5920 79
合計 81144 52816 65
セグメント 実サイズ 常駐サイズ 常駐率
データ 75984 49120 65
スタック 1480 1480 100
ISM型共有メモリ 377368 377368 100
プライベート型共有メモリ 8 8 100
共用ライブラリ 24088 17472 73
テキスト 416408 194504 47
Total 895336 639952 71

                         【備考】

1. 単位は1024バイト(1キロバイト)です。
2. シナリオ番号は42です。
3. 常駐率は、常駐サイズを実サイズで割ったパーセンテージです。

表の値ではイメージがつかみにくいのでピボットグラフにしてみました。

図5.3 ORACLE起動前のユーザセグメント

ORACLEを起動するとISM型共有メモリと、テキストセグメント、およびデータセグメントが増加します。次にORACLE起動後のユーザセグメントを示します。図5.3から比べて、値の単位が大きく、10倍になっています。

図5.4 ORACLE起動後のユーザセグメント

ここで、メモリ量を大きく見積もる場合は実サイズ、ワーキングセットとして見積もる場合は常駐サイズを用いてメモリサイジングします。なお、正確なワーキングセットの求め方は次のEワーキングセットはどう計測するのか? をご覧ください。


Eワーキングセットはどう計測するのか?

経験則として、プログラムは時間的、空間的に80パーセントの処理をそのプログラムの20パーセントのコードで実行すると言われています。これを20/80の法則と言います。言い換えれば、ワーキングセットはプログラムの20パーセントであると考えることが出来ます。ここでは、このワーキングセットを実際に計測する一つの方法を解説します。

シナリオ番号43はワーキングセットがどのように変化するのかを計測したものです。定常的に仕事をしているORACLEのチェックポイントプロセスに着目して、一旦ページアウトされた後、どの程度のページが呼び戻されるのか、また、どれだけのページが定常的にメモリに残されるのかを確認しました。

システムの振る舞いは図6.1のようになっています。

解説 グラフ
CPU使用状況です。%wioがページングのために高くなっ
ています。
9時39分50秒頃、メモリを大量に消費するプロセスを
実行して、参照されていない領域をページアウトします。

シナリオ番号:43 os
9時41分20秒以降、ページにタッチすることにより、
ページフォルトが発生してページインされます。

シナリオ番号:43 os

図6.1 メモリスィープアウト(掃除)の振る舞い

時間経過とともに、チェックポイントプロセスがどのようなメモリ状態になっていたのか、pmapコマンド-xオプションによって採取したユーザセグメントマップを表6.1にまとめました。値の単位は1024バイト(1キロバイト)です。チェックポイントプログラム本体のテキスト部分は、一時的に常駐率19パーセントまで低下しています。共用ライブラリのlibjpx9.soも22パーセントになっています。SGAはページアウトされないため、常に100パーセントの常駐率です。15時10分頃になると、常駐率は36〜41パーセントとなっており、徐々にメモリページが増加していることが分かります。ページアウトされた直後は、経験則の20/80の法則に近い値、20パーセントになっています。時間経過とともに、常駐率は高くなり、結果、約40パーセント程度まで上昇しています。

表6.1 チェックポイントプロセスセグメントマップの変化

PID:465 ora_ckpt Mapped File RealSize ResidentSize 常駐率% 
Address Permis
sions
【備考】
Kbytes 09:38:58 09:39:30 09:41:23 09:43:58 15:10:14 09:38:58 09:39:30 09:41:23 09:43:58 15:10:14
00010000 r/e oracle 37,176 17,456 17,480 7,048 9,768 14,424 47 47 19 26 39
0246C000 r/w/e oracle 304 304 304 184 192 272 100 100 61 63 89
024B8000 r/w/e [ heap ] 1,552 1,440 1,440 528 528 528 93 93 34 34 34
80000000 r/w/e/s [ism shmid=0x81] 377,368 377,368 377,368 377,368 377,368 377,368 100 100 100 100 100
FEA82000 r/w/e [ anon ] 8 8 8 8 8 8 100 100 100 100 100
FEA94000 r/w/e [ anon ] 8 8 8 - - - 100 100 0 0 0
FEAA6000 r/w/e [ anon ] 8 8 8 8 8 8 100 100 100 100 100
FEAB8000 r/w/e [ anon ] 8 8 8 - - - 100 100 0 0 0
FEACA000 r/w/e [ anon ] 8 8 8 - - - 100 100 0 0 0
FEADC000 r/w/e [ anon ] 8 8 8 - - - 100 100 0 0 0
FEAEE000 r/w/e [ anon ] 8 8 8 - - - 100 100 0 0 0
FEAFC000 r/w/e [ anon ] 8 8 8 8 8 8 100 100 100 100 100
FEB00000 r/w/e [ anon ] 8 8 8 8 8 8 100 100 100 100 100
FEB0E000 r/w/e [ anon ] 8 8 8 8 8 8 100 100 100 100 100
FEB12000 r/w/e [ anon ] 8 8 8 - - - 100 100 0 0 0
FEB20000 r/w/e [ anon ] 8 8 8 8 8 8 100 100 100 100 100
FEB24000 r/w/e [ anon ] 8 8 8 - - - 100 100 0 0 0
FEB32000 r/w/e [ anon ] 8 8 8 8 8 8 100 100 100 100 100
FEB36000 r/w/e [ anon ] 8 8 8 - - - 100 100 0 0 0
FEB44000 r/w/e [ anon ] 8 8 8 8 8 8 100 100 100 100 100
FEB48000 r/w/e [ anon ] 8 8 8 - - - 100 100 0 0 0
FEB56000 r/w/e [ anon ] 8 8 8 - - - 100 100 0 0 0
FEB5A000 r/w/e [ anon ] 8 8 8 - - - 100 100 0 0 0
FEB68000 r/w/e [ anon ] 8 8 8 - - - 100 100 0 0 0
FEB6C000 r/w/e [ anon ] 8 8 8 - - - 100 100 0 0 0
FEB7A000 r/w/e [ anon ] 8 8 8 - - - 100 100 0 0 0
FEB7E000 r/w/e [ anon ] 8 8 8 8 8 8 100 100 100 100 100
FEB8C000 r/w/e [ anon ] 8 8 8 8 8 8 100 100 100 100 100
FEB90000 r/w/e [ anon ] 8 8 8 - - - 100 100 0 0 0
FEB9E000 r/w/e [ anon ] 8 8 8 - - - 100 100 0 0 0
FEC00000 r/e libjox9.so 4,184 2,984 2,984 936 936 1,512 71 71 22 22 36
FF024000 r/w/e libjox9.so 160 160 160 96 96 128 100 100 60 60 80
FF04C000 r/w/e libjox9.so 8 - - - - - 0 0 0 0 0
FF080000 r/w/e/s [ anon ] 8 8 8 8 8 8 100 100 100 100 100
FF090000 r/e libmp.so.2 16 16 16 16 16 16 100 100 100 100 100
FF0A4000 r/w/e libmp.so.2 8 8 8 8 8 8 100 100 100 100 100
FF0B0000 r/e libm.so.1 88 80 80 64 72 80 91 91 73 82 91
FF0D4000 r/w/e libm.so.1 8 8 8 8 8 8 100 100 100 100 100
FF0E0000 r/e libkstat.so.1 8 8 8 8 8 8 100 100 100 100 100
FF0F2000 r/w/e libkstat.so.1 8 8 8 8 8 8 100 100 100 100 100
FF100000 r/e libc.so.1 680 664 664 632 648 648 98 98 93 95 95
FF1BA000 r/w/e libc.so.1 32 32 32 32 32 32 100 100 100 100 100
FF1D0000 r/e librt.so.1 24 24 24 24 24 24 100 100 100 100 100
FF1E6000 r/w/e librt.so.1 8 8 8 8 8 8 100 100 100 100 100
FF1F0000 r/e libaio.so.1 32 32 32 32 32 32 100 100 100 100 100
FF208000 r/w/e libaio.so.1 8 8 8 8 8 8 100 100 100 100 100
FF210000 r/w/e [ anon ] 8 8 8 8 8 8 100 100 100 100 100
FF220000 r/e libsched.so.1 8 8 8 8 8 8 100 100 100 100 100
FF232000 r/w/e libsched.so.1 8 8 8 - - 8 100 100 0 0 100
FF240000 r/e libgen.so.1 24 24 24 24 24 24 100 100 100 100 100
FF256000 r/w/e libgen.so.1 8 8 8 8 8 8 100 100 100 100 100
FF260000 r/e libsocket.so.1 40 40 40 40 40 40 100 100 100 100 100
FF27A000 r/w/e libsocket.so.1 8 8 8 8 8 8 100 100 100 100 100
FF280000 r/e libnsl.so.1 560 408 408 352 352 368 73 73 63 63 66
FF31C000 r/w/e libnsl.so.1 32 32 32 32 32 32 100 100 100 100 100
FF324000 r/w/e libnsl.so.1 32 24 24 16 16 16 75 75 50 50 50
FF340000 r/e libc_psr.so.1 8 8 8 8 8 8 100 100 100 100 100
FF350000 r/e libskgxp9.so 8 8 8 8 8 8 100 100 100 100 100
FF360000 r/w/e libskgxp9.so 8 8 8 - - 8 100 100 0 0 100
FF370000 r/e libodmd9.so 8 8 8 8 8 8 100 100 100 100 100
FF380000 r/w/e libodmd9.so 8 8 8 8 8 8 100 100 100 100 100
FF390000 r/e libdl.so.1 8 8 8 8 8 8 100 100 100 100 100
FF3A0000 r/w/e [ anon ] 8 8 8 8 8 8 100 100 100 100 100
FF3B0000 r/e ld.so.1 152 152 152 152 152 152 100 100 100 100 100
FF3E6000 r/w/e ld.so.1 8 8 8 8 8 8 100 100 100 100 100
FFBE6000 r/w/e [ stack ] 40 40 40 32 32 32 100 100 80 80 80
-------- ------ ------ ------ ------ ------ ------ ------ ------ ------ ------ ------
total Kb 422,872 401,648 401,672 387,832 390,584 395,968 53 53 23 23 41

【備考】Permissionsの表記について。
r/e    :read/exec
r/w/e  :read/write/exec
r/w/e/s :read/write/exec/shared

 

ORACLEチェックポイントプロセスはこのような所見になります。これらのことから、当該プロセスのテキストセグメントは、39パーセントがワーキングセットであり、ページアウト後に呼び戻されるバイト数は8パーセント、2,974キロバイト(約3メガバイト)になります。共用ライブラリlibjox9.soは36パーセントがワーキングセットであり、ページアウト後に呼び戻されるバイト数は586キロバイトになります。関連するデータ、ヒープ、およびスタックセグメントのサイズは元の常駐サイズに戻っているものと戻っていないものがあります。プログラムの構造やデータ領域の使い方で違いがあるようです。時系列に当該プロセスのセグメント情報をまとめたものが表6.2です。

表6.2 チェックポイントプロセスのセグメント

時間 txt rtxt shs rshs shm rshm dsz rdsz hsz rhsz rsh rrsh ssz rssz
09:38:58 37,176 17,456 5,848 4,472 377,368 377,368 888 872 1,552 1,440 0 0 40 40
09:39:30 37,176 17,480 5,848 4,472 377,368 377,368 888 872 1,552 1,440 0 0 40 40
09:41:23 37,176 7,048 5,848 2,320 377,368 377,368 888 536 1,552 528 0 0 40 32
09:43:58 37,176 9,768 5,848 2,344 377,368 377,368 888 544 1,552 528 0 0 40 32
15:10:14 37,176 14,424 5,848 2,944 377,368 377,368 888 672 1,552 528 0 0 40 32
【備考】値の単位は1024バイト(1キロバイト)です。 

一方、システム全体の所見はどのようになっているのでしょうか。表6.3に全プロセスのセグメントをまとめました。このことから、本システムでは、ページアウトされた直後は20/80の法則に近い値になっていますが、時間が経過すると26〜39パーセントに常駐率が上昇することがわかりました。

表6.3 プロセス全体のセグメント状態

項目 09:38:58 09:39:30 09:41:23 09:43:58 15:10:14
常駐 常駐率 常駐 常駐率 常駐 常駐率 常駐 常駐率 常駐 常駐率
データ 75,648 48,728 64 78,168 51,272 66 77,936 32,952 42 75,488 31,664 42 78,624 37,560 48
スタック 1,424 1,424 100 1,592 1,592 100 1,560 1,048 67 1,432 968 68 1,592 1,176 74
ISM共有メモリ 377,368 377,368 100 377,368 377,368 100 377,368 377,368 100 377,368 377,368 100 377,368 377,368 100
共有メモリ 8 8 100 8 8 100 8 8 100 8 8 100 8 8 100
共用ライブラリ 24,088 17,440 72 24,104 17,456 72 24,104 4,096 17 24,088 4,128 17 24,096 6,344 26
テキスト 416,424 197,960 48 416,528 198,328 48 416,528 78,888 19 416,408 108,984 26 416,600 160,952 39
合計 894,960 642,928 72 897,768 646,024 72 897,504 494,360 55 894,792 523,120 58 898,288 583,408 65
【備考】値の単位は1024バイト(1キロバイト)です。

図6.2は表6.3をもとにピボットグラフにしたものです。なお、ISM型共有メモリの常駐サイズは実サイズと同じです。グラフのハイライトを明らかにするためにサイズ(縦軸)の初期値を350メガバイトにしています。


図6.2 プロセス全体のセグメント状態

以上のように、プロセス単独および、システム全体で計測することでワーキングセットを明らかにし、実際に必要なメモリ量を測ることが出来ます。

 

Copyright (C) 2004 by The Art of Computer Technologies, Corp.  All rights reserved.