gpt4 book ai didi

java - 是否可以在( native )调用过程中的对象上调用终结器?

转载 作者:行者123 更新时间:2023-11-30 06:24:14 25 4
gpt4 key购买 nike

我们发现一个奇怪的 AddressSanitizer (clang/C++)“释放后堆使用”违规,可能与终结器极端情况有关。

假设一个 Java 对象 OBJ 有一个指向 native 资源 X 的句柄。之前创建 OBJ 的线程现在正在调用 OBJ.method(),该方法调用一个(静态) native 方法 staticMethod( X),其中使用X。

现在,我们几乎同时看到一个线程正在删除 native 资源 X。我们强烈假设这是由调用 OBJ.finalize() 的终结器触发的,它确实“删除了 X”。

对于终结器来说,这是有效的做法吗?

(OpenJDK 8)

最佳答案

一种安全的方法似乎是使用非静态 native JNI 方法。

在 C/C++ 中,静态 JNI 方法签名如下所示:

extern "C" JNIEXPORT jobject JNICALL
Java_com_example_MyClass_myMethod(JNIEnv* env, jclass type, jlong handle);

注意第二个参数jclass type传递Java类的JNI表示。

但是,非静态 JNI 方法接受当前 Java 实例对象 (this),如下所示:

extern "C" JNIEXPORT jobject JNICALL
Java_com_example_MyClass_myMethod(JNIEnv* env, jobject thisObj, jlong handle);

背景:虚拟机似乎非常积极地优化垃圾收集。仍在运行(非静态)方法但仅调用 native 静态方法的线程不会阻止释放对象。然而,如果 JNI 方法是非静态的,这会告诉 VM Java 对象仍在被引用。然后,只有当调用返回时,该对象的 native 引用才会被清除。因此,在此之前不允许运行任何终结器。

关于java - 是否可以在( native )调用过程中的对象上调用终结器?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47532395/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com