简体   繁体   English

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

[英]How to enforce garbage collector to call finalize method first, before cleaning up reference of unused objects

I have a scenario which uses a C library using JNA:我有一个使用 JNA 的 C 库的场景:
I have override the finalize method where I send the call to delete the object that is created through C.我已经覆盖了 finalize 方法,在该方法中我发送了删除通过 C 创建的对象的调用。
My code looks somewhat like this:我的代码看起来有点像这样:

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 is the API, which deletes the object created in the C library. sntl_licensing_app_context_delete是API,用于删除C库中创建的对象。
nativeAppContext is PointerByReference and nativeAppContext.getValue() sends the pointer of the object to be deleted. nativeAppContext是 PointerByReference 并且nativeAppContext.getValue()发送要删除的对象的指针。
What is happening right now is, when GC is called a crash occurs because the nativeAppContext reference is cleaned first by GC and since it does not find any reference so when it tries to get the value for sending to C library it crashes.现在发生的事情是,当 GC 被调用时会发生崩溃,因为nativeAppContext引用首先被 GC 清理,并且因为它没有找到任何引用,所以当它试图获取发送到 C 库的值时它崩溃了。

Is there any way to enforce GC to call finalize method first before cleaning up the objects?有没有办法强制GC在清理对象之前先调用finalize方法?

In this case, I assume GC cleans up the object first and then calls the finalize method.在这种情况下,我假设 GC 先清理对象,然后调用finalize方法。

It is and it is only guaranteed that the finalize() method is called before the object is cleaned by the GC.它是并且只能保证在对象被 GC 清理之前调用 finalize() 方法。

What you are trying to do is just not what finalize() is made for.您要做的不是 finalize() 的用途。 I never known when the GC will clean up the instance you used.我不知道 GC 何时会清理您使用的实例。 It's not like a descructor in C++.它不像 C++ 中的解析器。 It will not immediatelly be called after a variable gets out of scope.变量超出范围后不会立即调用它。 Therefore using finalize() for your cleanup code will hold open your C library for much more time then needed.因此,对您的清理代码使用 finalize() 将使您的 C 库打开所需的时间更长。

What you are looking for is probably the close() method of the interfaces java.io.Closeable or java.lang.AutoCloseable .您正在寻找的可能是接口java.io.Closeablejava.lang.AutoCloseable的 close() 方法。

Instead of putting your code in the finalize() method but it in there and mark your class implements AutoCloseable .而不是将您的代码放在 finalize() 方法中,而是将它放在那里并标记您的类implements AutoCloseable Then when you construct your instance of your class use a try-with-resouces block.然后,当您构建类的实例时,请使用 try-with-resources 块。 When this block gets exited, the close() -method will be called automatically.当这个块退出时, close()方法将被自动调用。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM