JVMのメモリが足りなくなってOOMKillerにころされてたアプリケーションの調査をした時のログです。
GCViewerを使ってGCのログファイルを確認してメモリ使用量の推移を見ました。
その前にJavaのメモリ管理の概要についても整理し直したので記載しています。
Javaのメモリ管理の概要
GCViewerを見るときにはJavaのメモリ管理の前提知識が必要になります。
こちらの記事が大変参考になりました。ありがとうございます。
http://qiita.com/opengl-8080/items/64152ee9965441f7667b
超ざっくりとした、メモリ構造を表した図。
おおきく、ヒープ(Heap)領域とネイティブ(Native)領域の2つの領域がある。
ヒープは Java プログラムが使う領域で、プログラム上で生成したオブジェクトは、このヒープ領域に配置される。
一方、ネイティブ領域は JVM が動くのに必要なメモリやスレッドのスタックを管理するのに使用される。
上記からヒープの中にもYoung(New)とOld(Tenurd)がある事がわかります。
GCの流れは下記のようになっているみたいです。
- 新しく作成されたオブジェクトはYoung領域のEden領域に保存される
- EdenがいっぱいになるとNew領域のGC(Scavenge GCと呼ばれる。ちょくちょく実行される)が走り、ここで破棄されなかったオブジェクトはEdenからSurvivor領域にオブジェクトが移動される
- 次にScavenge GCが走るとEdenからSurvivorへの移動は同じで、Survivor領域にいたオブジェクトで破棄されなかったものはもう一方のSurvivor領域に移動される
- これを繰り返し、異動の回数がしきい値を超えるとそのオブジェクトはOld領域に移動される
- Old領域もいっぱいになるとFull GCが走るが、これは処理に時間がかかるためこの回数は減らすべき
参考ページ
http://qiita.com/taisho6339/items/a6a7954bd473e16706bd
http://blog.pepese.com/entry/20120508/1336467306
http://www.whitemark.co.jp/tec/java/javagc.html
以上を踏まえてGCViewerを使ってみる
https://github.com/chewiebug/GCViewer/wiki/Changelog
上記がアプリケーションダウンロードのURLです。
使い方
ダウンロードしたアプリケーションを開いてGCのログファイルをドラッグ&ドロップするだけです。簡単でした。
見方
最初はたくさん線や領域が表示されているのですが、Viewの設定から必要なものだけに絞りました。
表示している領域と先は以下のとおりです。
- ピンクがOld領域
- 黄色がYoung領域
- ピンクの中にあるピンクの線がOld領域のヒープの使用量
- 黄色の中にある灰色の線がNew領域のヒープの使用量
- 青い線が全体のヒープ領域の使用量
- 黒い線がFullGCが走ったとき
上記から、一番右の黒い線が密集してる部分でメモリが足りなくなってOOMKillerが走ったと推測できました。
おまけ
メモリを増やした後のGCViewerの出力です。
安定してました。
以上です。