2017-11-28 10 views
0

ファイナライザのコーナーケースに関連する恐れのあるAddressSanitizer(clang/C++)の "heap-after-after-free"違反があります。(ネイティブ)コールの途中にあるオブジェクトでファイナライザを呼び出せますか?

たとえば、JavaオブジェクトOBJがネイティブリソースXのハンドルを持っているとします。OBJを作成したスレッドは、OBJ.method()を呼び出しています。これは(静的な)ネイティブメソッドstaticMethod (X)で表され、Xが使用される。

これとほぼ同じ時間に、ネイティブリソースXを削除するスレッドが発生しています。これは、ファイナライザがOBJ.finalize()を呼び出すことによってトリガされることを強く前提としています。

これはファイナライザ用に有効なものですか? finalize()方法の

(OpenJDKの8)

答えて

0

デフォルトの実装は何もない:それは別のスレッドで必要とされている間に共有ネイティブリソースが1つのスレッドで削除されたよう

public class Object { 
    protected void finalize() throws Throwable { } 
} 

あなたの説明は鳴りません。 ネイティブのメソッド(java)をチェックして、ネイティブメモリスペースから何かを削除する必要があります。
Javaはネイティブコードで割り当てられたオブジェクトについて知らない。ネイティブコールでこれを手動で制御する必要があります。たとえば、

public class A { 
    private int id; 

    static { 
     // load native library 
    } 

    public A(int id) { 
     // create required native resources for this instance 
     allocateAContext(id) 
    } 

    // this method will create required native resources out of java heap 
    protected native void allocateAContext(int id); 

    // this method will remove allocated native resources 
    protected native void deleteAContext(int id); 

    @Override 
    protected void finalize() throws Throwable { 
     super.finalize(); 
     // release native resources when garbage collector will remove A object 
     deleteAContext(id); 
    } 
} 
+0

ありがとうございました。あなたの答えが私の質問にどう関係しているのか分かりません。これはJNIの基本ではなく、非常に特殊なコーナーケースです。 –