2011-12-13 15 views
12

私は瀕死のアプリケーションから作成したメモリダンプを持っています。使用可能なすべてのヒープ(-Xmx1024m)を消費しました。 com.gargoylesoftware.htmlunit.WebClientを使用してWebページをクロールします。 1分あたりいくつかのHTTPリクエストを作成し、数日で終了します。ダンプから見ると、HtmlPageクラスの〜1750インスタンスがあり、それぞれがクロールされたページの完全な内容を含む関連オブジェクトのトーンを持っています。ハンティングメモリリーク、VisualVM: "GCルートが見つかりません"。次は何ですか?

HtmlPageがガベージコレクションされない理由を理解できません。私はインスタンス参照を調査しましたが、参照を保持しているコードは表示されません.VisualVMには「GCのルートが見つかりません」というメッセージが表示されます。私が理解しているように、オブジェクトがgcに適格であることを意味するはずですが、動作しません。

アプリケーションは単純なスタンドアロンプ​​ロセスとして実行されており、Webコンテナやアプリケーションサーバーは使用しません。

ヒント他に何を調べるべきですか?

仕様:

  • htmlunitのV2.7
  • Javaのバージョン "1.6.0_13" のJava(TM)SEランタイム環境(ビルド1.6.0_13-B03) は、Java HotSpot( TM)Server仮想マシン(Linuxはmy.lan
  • 11.3-B02、混合モード)を構築2.6.18-128.el5#1 SMP水曜日12月17日11時42分39秒EST 2008 i686のi686のi386のGNU/Linuxの

アップデート1

私はYourKitのJavaプロファイラでダンプを分析することを試みました。それは私に多くのjava.lang.ref.Finalizerオブジェクトが310メガバイト保持されていることを示しています。それらはnet.sourceforge.htmlunit.corejs.javascript.NativeGenerator#finalize()ファイナライザ用に作成され、NativeGeneratorWindowを指し、HtmlPageとすべてを指します。

誰もがなぜ彼らは記憶に残っているのか分かりませんか?

ノート:奇妙ですが、VisualVMは「保留中のファイナライズ」をゼロとして示していました。

+0

JVMに特定のコマンドライン引数を使用しましたか? –

+0

@ThomasJungblut '-Xmx1024m -XX:MaxPermSize = 128m -XX:+ PrintGCDetails -XX:+ PrintGCTimeStamps -XX:+ UseConcMarkSweepGC' – kan

+0

また、htmlunit 2.8でメモリリークが発生しています。回避策として、WebClientを1日1回再インスタンス化します。このバグを追跡できることを願っています。 – milan

答えて

1

あなたは、ページ(複数可)で終わった後、あなたがwebClient.closeAllWindows()を呼び出していることを確認します - それ以外の場合は、JavaScriptのスレッドがオブジェクトを非がある場合などのページのリソース

+1

私は'(setJavaScriptEnabledています偽) '。小さなテストをしようとし、 'closeAllWindows'がなくてもうまくいくようです。しかし、私は試し続けます... – kan

+0

私はXmlUnitでクロールする理由は、ページ上でJavaScriptを使用できるようになると思っていたでしょう。ああよく;) – maximdim

+0

いくつかの他のページ(異なるプロセスでクロールする)はjavascriptを使用しますが、この特定のアプリはそれを必要としませんが、より頻繁にクロールします。 – kan

1

に保持する参照を実行し続けています簡単なfinalize()メソッドでは、オブジェクトのインスタンスを作成するときに、JVMは、作成されたオブジェクトへの参照を保持するjava.lang.ref.Finalizerを作成し、finalize()メソッドが終了する前にガベージコレクションを行いません。メモリリークはjava.lang.ref.Finalizer-sが時間通りにクリアされないことに起因します。これらのファイナライザのクリアは、プライオリティの低い別のファイナライザデーモンスレッドによって行われるため、メモリが不足したときにfinalize()メソッドが実装されたオブジェクトのインスタンスを多数作成すると、

そのすべてに非常に良い説明:

http://www.fasterj.com/articles/finalizer2.shtml

これは、彼らが解決策として提案するものである:

ファイナライザ 『デーモンスレッド「1つの明白な方法は、の優先順位を上げることです』 - このためのAPIはありません。したがって、すべてのスレッドを実行して名前で検索し、優先順位を上げる必要があります。

幸運

関連する問題