- PR -

GC後のヒープサイズについて

1
投稿者投稿内容
ショウ
会議室デビュー日: 2004/10/14
投稿数: 15
投稿日時: 2005-10-31 09:55
Swingを使用した画面アプリを開発しております。
実行中にOutOfMemoryErrorが発生してしまいました。
実行時のオプションに「-Xloggc:FileName -XX:+PrintGCDetails」を指定しるので、GCとヒープメモリの状況を確認したところ、OutOfMemoryErrorが発生した時のログでは、FullGCが起きていても使用中ヒープメモリサイズがほとんど減少していませんでした。
しかし、OutOfMemoryErrorはその1度しか発生せず、その後何度実行しても問題なく動作し、ログを確認してもFullGCでは使用中ヒープメモリサイズは大きく減少していました。
OutOfMemoryErrorはメモリリークで発生すると思われるので、何かしら特定の操作を行うとメモリリークが発生してしまうという事も考えられますが、メモリリーク以外でFullGCでも使用中ヒープメモリサイズが減少しない状況というのはあるのでしょうか?

よろしくお願い致します。

【環境】
WindowsXP
j2sdk1.4.2_04
山本 裕介
ぬし
会議室デビュー日: 2003/05/22
投稿数: 2415
お住まい・勤務地: 恵比寿
投稿日時: 2005-10-31 10:05
十分にヒープ領域を確保しているのにも拘わらず OutOfMemoryError が発生するのであれば多くの場合はメモリリークと考えて差し支えないかと存じます。
今回は特に GC ログでヒープ使用量が減少していないのを確認されているとのことですので、なんらかのリークが発生しているのではないでしょうか。

負荷が高く、一時的に想定以上にヒープ領域を必要とするようなことがあればリークしていなくても OutOfMmeoryError となることがあります。たとえばヒープ領域以上のサイズの XML ドキュメントを DOM で保持しようとしたならば、その後ちゃんとオブジェクトを解放するとしてもヒープが足りなくなるのはあたりまえですよね。

あとは希にですがヒープ領域内のコンパクション処理がおいつかず、オブジェクトを配置する連続領域がなくて、ヒープ領域が足りているにもかかわらず OutOfMemoryError が発生することがあります。ちょっと前の JRockit や、IBM の JDK で良く発生すると聞いたことがあります。

OutOfMemoryError の原因を体系的に切り分ける方法は以下のドキュメントがとても詳しいです。
・BEA トラブルシューティング ガイド > メモリ不足とメモリ リークに関する問題の調査
http://www.beasys.co.jp/cs/support_news/product_troubleshooting/Investigating_Out_of_Memory_Memory_Leak_Pattern.html
ショウ
会議室デビュー日: 2004/10/14
投稿数: 15
投稿日時: 2005-10-31 15:23
早々の返答ありがとうございます。

> 負荷が高く、一時的に想定以上にヒープ領域を必要とするようなことがあればリーク
> していなくても OutOfMmeoryError となることがあります。たとえばヒープ領域以上
> のサイズの XML ドキュメントを DOM で保持しようとしたならば、その後ちゃんとオ
> ブジェクトを解放するとしてもヒープが足りなくなるのはあたりまえですよね。
ヒープ領域以上のファイルを保持していないため、この原因ではなさそうです。

> あとは希にですがヒープ領域内のコンパクション処理がおいつかず、オブジェクトを
> 配置する連続領域がなくて、ヒープ領域が足りているにもかかわらず
> OutOfMemoryError が発生することがあります。ちょっと前の JRockit や、IBM の
> JDK で良く発生すると聞いたことがあります。
OutOfMemoryErrorが発生した時に空きヒープもなくなっていることをログで確認できるので、コンパクションによるものではなさそうです。

となると、やはりリークが発生しているのでしょうか?
発生した時の詳細な操作がわからないため、まったく同じ操作ではありませんが、ほぼ同じ操作を(繰り返し)行ってもOutOfMemoryErrorが発生しないので他の原因を疑っていました。
その特定できていない操作でリークが発生しているのかもしれません。

他の原因で例えば「New・Old・Survivor領域の割合」や「特定のハード構成」によってOutOfMemoryErrorが発生する可能性はあるのでしょうか?
再現できないことに引っかかっています。繰り返し同じような質問になってしまい申し訳ございません。

よろしくお願い致します。
山本 裕介
ぬし
会議室デビュー日: 2003/05/22
投稿数: 2415
お住まい・勤務地: 恵比寿
投稿日時: 2005-10-31 16:35
ハードウェア構成、については通常関係ありません。

世代別GC機構をもつ JVM であれば特定の世代だけいっぱいになって OOM になることはあるかもしれませんね。しかし、今回は OOM になったときのヒープ使用量がほぼいっぱいだったということなので Old 領域までいっぱいになっていたものと考えられます。

検証環境での再現ができないのであれば JVM を JRockit にして、Ctrl Break ハンドラを利用して定期的にヒープ内容のスナップショットをとって解析してみてはいかがでしょう。
プロファイラを使ったときのように動作速度を落とすことないので、運用環境でも安心してリークしたオブジェクトを確認することができます。
http://www.beasys.co.jp/dev2dev/products/wljrockit142/articles/jrockit142_hirt.html
http://pcweb.mycom.co.jp/articles/2005/10/25/beaworld1/

JVM の問題に起因する現象であれば、JRockit はまったく異なる機構をもっているのでそもそも現象が発生しなくなる可能性もあります。世界記録をもっている JVM ですからついでにパフォーマンスの向上も期待できますし。

JRockit にしなくても、JVM を Sun 製で最新の J2SE v 1.4.2_09 SDK にするのも良いかと。
1

スキルアップ/キャリアアップ(JOB@IT)