我有一个使用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_licensing_app_context_delete
是API,用于删除在C库中创建的对象
nativeAppContext
是PointerByReference,nativeAppContext.getValue()
发送要删除的对象的指针
现在发生的事情是,当GC被调用时发生崩溃,因为nativeAppContext
引用首先被GC清理,因为它没有找到任何引用,所以当它试图获取发送到C库的值时它会崩溃。
在清理对象之前,有没有办法强制GC先调用finalize方法?
在这种情况下,我假设GC首先清理对象,然后调用finalize
方法。
答案 0 :(得分:1)
确保在GC清理对象之前调用finalize()方法。
你要做的不仅仅是终结()。我从来不知道GC什么时候会清理你使用的实例。它不像C ++中的descructor。在变量超出范围后,不会立即调用它。因此,使用finalize()作为清理代码将保持打开C库所需的时间更长。
您正在寻找的可能是接口java.io.Closeable
或java.lang.AutoCloseable
的close()方法。
不是将代码放在finalize()方法中,而是将其放在那里并标记您的类implements AutoCloseable
。然后,当您构建类的实例时,请使用try-with-resouces块。退出此块后,将自动调用close()
- 方法。
try (MyClass myInstance = new MyClass()) {
// use myInstance here
}
// myInstance.close() will have been called here automatically