Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/308.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/65.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何强制垃圾收集器在清理未使用对象的引用之前首先调用finalize方法_Java_C_Garbage Collection - Fatal编程技术网

Java 如何强制垃圾收集器在清理未使用对象的引用之前首先调用finalize方法

Java 如何强制垃圾收集器在清理未使用对象的引用之前首先调用finalize方法,java,c,garbage-collection,Java,C,Garbage Collection,我有一个使用JNA的C库的场景: 我已重写finalize方法,在该方法中,我发送了删除通过C创建的对象的调用。 我的代码看起来有点像这样: protected void finalize() throws Throwable { if (LicensingAPIHelper.instance == null) throw new NullPointerException("LicensingAPIHelper is not initialized

我有一个使用JNA的C库的场景:
我已重写finalize方法,在该方法中,我发送了删除通过C创建的对象的调用。
我的代码看起来有点像这样:

protected void finalize() throws Throwable
    {
        if (LicensingAPIHelper.instance == null)
            throw new NullPointerException("LicensingAPIHelper is not initialized");
                   LicensingAPIHelper.instance.sntl_licensing_app_context_delete(nativeAppContext.getValue());
    }
sntl\u licensing\u app\u context\u delete
是用于删除在C库中创建的对象的API。
nativeAppContext
是指针引用,并且
nativeAppContext.getValue()
发送要删除的对象的指针。
现在发生的情况是,当调用GC时,会发生崩溃,因为
nativeAppContext
引用首先被GC清除,并且由于它找不到任何引用,所以当它试图获取发送到C库的值时,会崩溃

有没有办法强制GC在清理对象之前先调用finalize方法


在这种情况下,我假设GC首先清理对象,然后调用
finalize
方法。

确实如此,并且只保证在GC清理对象之前调用finalize()方法

您试图做的并不是finalize()的目的。我不知道GC何时会清理您使用的实例。它不像C++中的一个解构主义者。变量超出范围后不会立即调用它。因此,在清理代码中使用finalize()将使打开C库的时间比需要的时间长得多

您要查找的可能是接口
java.io.Closeable
java.lang.AutoCloseable
的close()方法

不要将代码放在finalize()方法中,而是将它放在那里,并标记类
实现自动关闭
。然后,在构造类实例时,使用try with resources块。退出此块时,将自动调用
close()
-方法

try (MyClass myInstance = new MyClass()) {
    // use myInstance here
}
// myInstance.close() will have been called here automatically

不,我想你不行。您可能需要一个更手动的清理过程。我相当确定GC在销毁对象之前调用
finalize
。。。(否则,就不会有一个对象来调用finalize…)我也有同样的印象,GC首先调用finalize,但当我在向C库发送调用之前检查引用值时,这是空的。所以我假设GC必须清除对象,因此引用是空的。我已经做了你声称不起作用的事情:使用<代码>终结()/<代码>方法作为删除关联C++对象的时机。但是我把C++指针保存为当前类中的<代码>长< /C>。你似乎把终结器放错了类。@EJP是的,这就是我想知道的,如果我做错了什么。我在everyclass中使用了finalie()方法。并调用deleteAPI from finalize方法,因此当对象超出范围时,将调用finalize()并删除关联的C对象。如果我错了,请纠正我。谢谢你的建议!java7中引入了Closeable和AutoCloseable。Java6用户呢?他们如何做到这一点?我还有一个查询:所以您试图说,我不能在finalize()方法中调用本机库API。正确的?因为如果finalize()是在变量超出作用域后立即调用的,那么fainalize()中的第一个调用就是调用C库来删除对象,这本来会被调用的,但不会发生。那么,对第三个库的任何API调用都不能通过finalize()方法完成吗?finalize()只是在变量超出范围后不会立即调用。这是Java的设计。如果您仍然需要支持旧版本的Java,那么方法就是将其实现为close()方法,但您必须在变量超出范围之前自行调用此close()方法。在版本6之前的Java上没有自动操作。非常感谢!这意味着我需要手动调用C的这个deleteAPI。再次感谢!