質問

jProfiler を使用して Java Swing アプリケーションのメモリ リークを見つけています。数が増え続ける JFrame のインスタンスを特定しました。

このフレームは開いてから閉じられます。

jProfiler を使用して GC ルートへのパスを表示すると、「JNI グローバル参照」という参照が 1 つだけあります。

これはどういう意味ですか?フレームの各インスタンスにぶら下がっているのはなぜですか?

役に立ちましたか?

解決

ウィキペディアには概要がよく載っています Javaネイティブインターフェース, 、本質的には、Java と他の言語で書かれたネイティブ オペレーティング システム ライブラリ間の通信を可能にします。

JNI グローバル参照は自動的にガベージ コレクションされないため、メモリ リークが発生しやすく、プログラマが明示的に解放する必要があります。JNI コードを自分で作成していない場合は、使用しているライブラリにメモリ リークが発生している可能性があります。

編集 ここ ローカル vs. についてもう少し詳しく説明します。グローバル参照、およびグローバル参照が使用される理由 (およびグローバル参照を解放する方法)

他のヒント

JNI グローバル参照は、「ネイティブ」コードから Java ガベージ コレクターによって管理される Java オブジェクトへの参照です。その目的は、ネイティブ コードでまだ使用されているものの、Java コード内にライブ参照がないように見えるオブジェクトが収集されるのを防ぐことです。

JFrame は、 java.awt.Window, 、「ネイティブ」Window オブジェクトに関連付けられています。特定の JFrame インスタンスの使用が完全に終了したら、そのインスタンスを呼び出す必要があります。 dispose() 掃除する方法。

ネイティブ コードが JFrame へのグローバル参照を作成しているかどうかはわかりませんが、おそらくそうであると思われます。存在する場合、JFrame がガベージ コレクションされなくなります。多数の Windows (またはサブクラス) を作成していて、それらが収集されない場合は、それらが破棄されていることを確認してください。

JavaFX アプリケーションのメモリ リークを修正するときに、まさにこの問題が発生しました。結局、問題はアプリケーションを実行していたことであることが判明しました デバッグモード コードにはいくつかのブレークポイントがありました。これにより、オブジェクトが「JNI グローバル参照」となり、明らかな理由もなくメモリ内に保持されていたようです。デバッグモードをオフにすると、すべてが正常に動作しました。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top