前回cpuに負荷をかけてload averageをメッチャ上げてみたが、今度は、メモリをひたすら消費するとどうなるか見てみます。
今回もwatchdogタイマーの動作具合を見るのが目的です。
まず、以下のようなコードを書いて
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
#include <stdio.h> #include <stdlib.h> int main( ) { int i = 0; while (1){ char *str; /* 文字列のためのメモリを確保 */ str = (char *)malloc(1024); if(str == NULL) { printf("メモリが確保できません\n"); printf("10秒待ちます\n"); sleep(10); } if ( (i % 10240) == 0 ){ printf("%d MBytes\n", (i / 1024 )); } i++; } return 0; } |
コンパイルして、
1 |
./gcc -o mem_full mem_full.c |
実行します。
1 2 3 4 5 6 7 8 9 10 |
$ ./mem_full 0 MBytes 10 MBytes 20 MBytes -- snip -- 2600 MBytes 2610 MBytes 強制終了 |
メモリをジワリジワリと消費して行って、そのうち強制終了されると思います。
その間、経過を見るため他のコンソールでtopします。
1 2 3 |
$ top PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 7219 gpowers 20 0 867m 866m 344 R 73.0 45.7 1:32.67 mem_full |
RESの値が搭載メモリ近くになると、強制終了すると思います。このRESの値が実際に確保する値です。malloc時に
もっと多めに取れば、早く確保出来ると思ったのですが、あまり値が大きいと仮想メモリ(VIRT)ばかり増えて、
実メモリ(RES)が少ししか増えなかったので、小さめにしていっぱい回します。
RESが搭載メモリ近くになると、コンソールの反応とかも悪くなりますが、しばらくすると対象プロセス(mem_full)が
強制終了されます。この強制終了は、有名なoom-killerさんが行なってくれます。
syslogを見ればそんなメッセージがあると思います。
ただ、必ず予想していたプロセス(mem_full)とは限らず、他の正常プロセスも落とされる可能性があります。
ここまでやってメモリを食い尽くすプロセスがいても、きっとoom-killerさんが良きに計らってくれるので
watchdogタイマーで落ちることは無さそうです。
せっかくなので、今度は、メモリ食い尽くしプログラムを同時多発的に実行してみます。
1 |
$ for i in `seq 1 100`; do ./mem_full & done |
とりあえず100個実行します。topで見るとわんさかプロセスがいます。
コンソールのレスポンスも激遅になり、topの表示も更新されなくなるが
地味にoom-killerさんも動いており、watchdogのリセットが実行される形跡はありません。
watchdogデバイスに定期的に書き込んでいるのは、CentOSにあったその名もwatchdogな
パッケージでインストールしたデーモンなんですが、こいつが何とか頑張っているようです。
この状況だとコマンドも打てないので、強制的に電源を落とすしかありませんでした。
watchdogの意味なし。
一応CentOSのwatchdogでは、load averageにしきい値を設定出来そうなので
それで対処するのもありかと思います(未検証)。
ただしきい値の設定は頭の痛いところです。因みにこのテスト実施時は160くらいいってました。
また、デーモンタイプのwatchdogでは性能が良すぎるのかとも思います。都度コマンドを実行して
デバイスに書き込むタイプの簡易的なものなら、おそらくコマンドの実行が出来ずwatchdogからリセットがかかる可能性が高い気がします。
うーん。watchdogに期待しすぎなのかもしれません。