7

java.util.zipデータを圧縮/解凍するために呼び出し続けるJavaプログラムがあります。数秒以内にメモリが不足します。でメモリ ダンプを取得しjmap、 で表示していjhatます。

ファイナライザの概要が表示されますTotal instances pending finalization: 0。私が正しく理解していれば、(1) finalize() メソッドを持っている、(2) GC によってマークされている、(3) ファイナライズを待っているオブジェクトはありません。これは良さそうです。

特定のオブジェクトを見ると、このオブジェクトへの唯一の参照はjava.lang.ref.Finalizer. Finalizer オブジェクトは、オブジェクトが GC されているかどうかに関係なく、finalize() メソッドを持つ各オブジェクトに対して作成されます。したがって、このDeflaterオブジェクトが GC されることを妨げているものは何もないように見えます。

0x7f4aeb7a35d0 のオブジェクト

java.util.zip.Deflater@0x7f4aeb7a35d0 のインスタンス (51 バイト)

このオブジェクトへの参照:

java.lang.ref.Finalizer@0x7f4aeb8607c8 (64 バイト) : フィールド参照先

プログラムは によって実行中に一時停止されSystem.in.read()ます。しばらくメモリ使用量が減りません。

アップデート:

私はそれを明確にする必要があります。メモリ ダンプは、多くのオブジェクトが GC されていないことを示していますが、他のオブジェクト (ファイナライザー オブジェクトを除く) はそれらを参照していませんでした。GC されなかった理由を突き止めようとしています。

4

5 に答える 5

5

ストリームを閉じてendデフレーターで呼び出したのは確かですか?これがすでに試した単純な提案である場合は申し訳ありませんが、Deflaterすぐに呼び出さない場合に使用すると、メモリリークについて多くの苦情がありendました。たとえば、次のようになります。

根本的な原因は、ネイティブ要素によって使用されるメモリが関係している場合、コレクターがアプリケーションに追いつくことができないことです。これは、プロファイリング時に表示される動作も説明しています。メモリは再利用の準備ができていますが、十分な速さで再利用されていません。

直接ではなくDeflatorApacheThriftを使用して記述したので、そのライブラリ内のどのメソッドがデフレーターの終了に関与しているかを特定し、そのメソッドを呼び出したことを確認してください。

于 2012-11-25T11:29:30.910 に答える
1

基本的な問題は、C ヒープからオブジェクトを解放していないことです。java.util.zip の多くのクラスはDeflater. デフレーターは、C ヒープ内のデータへの参照を維持します。 コードが or を呼び出していないか、 を呼び出していない可能close()ZipOutputStreamDeflaterOutputStreamあります。end()Deflater

Deflater(自分自身をZipOutputStreamまたはに渡す場合は、DeflaterDeflaterOutputStreamを呼び出す責任があります。)end()

ストリームを逆参照して最終的にファイナライズする必要があるため、GC はあなたの場合にはあまり役に立ちません。これには複数の GC スイープが必要になる場合があります。Jettyで同様の問題が発生し、その修正を提案しました

于 2012-11-26T01:45:30.240 に答える
1

Marian-Daniel Craciunescuの回答に追加

私は別のタイプの使用でこの種の問題を抱えていました。

私が見つけた解決策は次のとおりです。

  • オブジェクトをマップまたはその参照を簡単にドロップできる場所に配置します
  • オブジェクトを使用するために、オブジェクトWeakReferenceに入れます
  • 通常どおり参照を使用する
  • 使用されなくなったマップから参照を削除します

継承された参照に注意してください

オブジェクトが別のオブジェクトで「hidden-inner-referenced」である可能性が非常に高く、デバッガーを使用し、それを使用するすべてのオブジェクトを「展開」します。

GC がいつ実行されているか、GC がを処理するかはわかりません(使用中のオブジェクトを除く)。

便利なリンク

まだ読んでいない場合は、WeakReferences に関するこの投稿を読む必要があります: Java の参照クラスについて: SoftReference、WeakReference、および PhantomReference

于 2012-11-30T16:28:44.923 に答える
0

まず、メモリリークについて考える前に、実行している処理でメモリ要件が正常であるかどうかを理解する必要があります。JVMで使用可能なメモリのサイズ、つまり-XmXはいくつですか。メモリのサイズを増やしたり、処理中のファイルのサイズを減らしたりしても機能しますか?

于 2012-12-01T13:52:26.370 に答える
-1

オブジェクトに WeakReference を使用する必要があるかもしれません。

http://docs.oracle.com/javase/1.5.0/docs/api/java/lang/ref/WeakReference.html http://weblogs.java.net/blog/2006/05/04/understanding-weak -参考文献

于 2012-11-28T12:08:57.650 に答える