ps aux
の結果でてくるRSS
(プロセスが実際に使用しているRAMの総メモリ量)の値を見て、Apacheのメモリ使用量を計算すると、Apacheの子プロセス間で共有しているメモリ分を重複してカウントしてしまい、実際よりもかなり大きい数値となってしまう。
子プロセス全てのRSSを足し合わせると、Webサーバでfree
コマンドを実行して出力される使用メモリ(-/+ bufferes/cache
のused
)を越えてしまうこともあるだろう。これは計算ミスでない限り、明らかにあり得ない。
実際に計算に使用する値は、プロセスが使用しているものと、共有ライブラリが使用しているものを合計し算出するRSSから、共有分を引いたものでなくてはいけない。
/proc/[pid]/smaps
は、プロセスの各マッピングのメモリ消費量を表示してくれる。
以下のような表記がマッピングごとに複数回現れるので、Rss、Shared、Privateで始まる行の値を全て足し合わせることで、このプロセスのメモリ消費量がわかる。
Size: 464 kB
Rss: 424 kB
Shared_Clean: 424 kB
Shared_Dirty: 0 kB
Private_Clean: 0 kB
Private_Dirty: 0 kB
※Rss、Shared、Privateの3つは次の関係性が成り立っている。
RSS = Shared + Private
これを踏まえた上でApacheの子プロセスが使用している全メモリを表示するコマンドを次に記載する。
echo -e "PID\tPPID\tRSS\tSHARED\tPRIVATE\tPRIVATE(RSS-SHARED)"; \
ps -ef|grep httpd|grep -v root|grep -v grep|while read line;do args=(${line});echo -ne ${args[1]}"\t"${args[2]}"\t";cat /proc/${args[1]}/smaps|awk 'BEGIN{rss=0;shared=0;private=0;}/Rss/{rss+=$2;}/Shared/{shared+=$2;}/Private/{private+=$2;}END{printf("%.1f\t%.1f\t%.1f\t%.1f\n",rss/1024,shared/1024,private/1024,(rss-shared)/1024);}';done \
| awk '{sum+=$5}END{print sum}'
3行に分けているが、1行目がヘッダを出力し、2行目で各値を出力する。3行目は2行目のコマンドで出力された各プロセスのPRIVATEメモリ使用量を全て足し合わせている。
目的に合わせて、2行目だけ実行したり、全行実行したりできるようになっている。
2行目のコマンドの内容は、まずps -ef | grep httpd
でApacheのプロセスIDを抜き出し、grep -v root
でApacheの親プロセスを対象外としている。各プロセスIDがわかれば/proc/[pid]/smaps
をcatできるので、catの結果をawkに渡して、Rss、Shared、Privateで始まる行の値を全て足し合わせている。
※今回の目的だけで言うと、本当はPRIVATEだけを出力すればいいが、情報の一覧性のため全て出力している。簡潔さを求めてPRIVATEだけを出力するコマンドも記載する。
echo -e "PID\tPPID\t\tPRIVATE"; \
ps -ef|grep httpd|grep -v root|grep -v grep|while read line;do args=(${line});echo -ne ${args[1]}"\t"${args[2]}"\t";cat /proc/${args[1]}/smaps|awk 'BEGIN{private=0;}/Private/{private+=$2;}END{printf("%.1f\n",private/1024);}';done \
| awk '{sum+=$3}END{print sum}'
参考:
Apacheのプロセス毎のメモリ使用量
proc - ファイルのフォーマットと規約の説明 - Linux コマンド集 一覧表