3

C ++でネイティブ実装ピアを作成する場合、JavaオブジェクトがJVMによって削除されたときに、ネイティブ部分も削除されるようにするにはどうすればよいですか?Javaオブジェクトのユーザーが明示的に呼び出さなければならないメソッドをいくつか追加できますが、c ++実装オブジェクトを自動的に削除できるように、Javaオブジェクトが削除された(ガベージコレクションされた)ときに処理できるフックがあるかどうかを知りたいです同じように。

JACEを確認したところ、そうなっているようですが、PeerEnhancerを実行して、生成されたクラスファイルにパッチを適用する必要があります(おそらく、それが削除をフックする方法ですか?または、他の何かのためにこのパッチを適用する必要があります)。ただし、コンパイルされたJavaファイルをいじりたくないので、派手なものは必要ありません。

4

2 に答える 2

4

ファイナライザーを採用することで、JVMを最悪の場所でくすぐることに注意してください。finalizer()でJNIを呼び出すことは、運転中にエンジンバルブタイミングを調整するようなものです。技術的には可能ですが、JVMのリークやクラッシュが発生する可能性も非常に高くなります。マルチスレッドを少しでもタッチするだけで、確実にある時点でデッドロック/クラッシュが発生します。「派手なものは何も欲しくない」と言うなら、明示的に呼び出されたメソッドを使うことをお勧めします。はい、慣例により特定のメソッドの順序を要求することはダーティな設計ですが、JNIは一般的にダーティです。

尊敬されているJNIライブラリが、単にファイナライザを使用するのではなく、覆面クラスのインストルメンテーションを実行する場合、おそらく理由があります。いくつかの推奨読書(そしてそれはJNIについても言及していません!):

http://asserttrue.blogspot.com/2008/11/finalization-is-evil.html

http://elliottback.com/wp/java-memory-leaks-w-finalize-examples/

私の提案は次のとおりです。はい、仮想メソッドdetachFromPeer()を使用してベースクラスを実装し、それに「デタッチ」フラグを設定してから、ファイナライザーで警告付きのフラグを確認します。

于 2012-10-24T09:41:58.837 に答える
2

これは、実際にファイナライザーを使用する必要があるまれなケースですが、JavaクラスもCloseableにする必要があります。

于 2012-10-24T00:27:13.837 に答える