检测 Java 对象的 GC 调用的最佳方法是什么?
我正在为 C++ 代码构建一个 Java Wrapper,每次调用 GC 时我都需要释放C++ 代码中分配的内存。
我看到了一些解决方案,但没有一个让我满意。
其中之一是:
Object obj = null;
try{
obj = new Object();
// do things
} finally {
if(obj != null){
obj.freeCObjects();
}
}
检测 Java 对象的 GC 调用的最佳方法是什么?
我正在为 C++ 代码构建一个 Java Wrapper,每次调用 GC 时我都需要释放C++ 代码中分配的内存。
我看到了一些解决方案,但没有一个让我满意。
其中之一是:
Object obj = null;
try{
obj = new Object();
// do things
} finally {
if(obj != null){
obj.freeCObjects();
}
}
您可能需要考虑在java.lang.Object
.
It is called by the garbage collector on an object when garbage collection determines
that there are no more references to the object.
一般来说,最好避免使用终结器,因为 JVM 不保证会finalize()
在任何对象上调用终结器,但是当需要清理本机(通常是非 Java)资源时,终结器可能很有用。
这是一个简单的例子:
Object obj = new Object() {
@Override
protected void finalize() throws Throwable {
System.out.println("finalize object");
super.finalize();
}
};
终结器可以被垃圾回收调用。
仅使用垃圾收集器没有可靠的方法来做到这一点。通常的方法(例如,由使用本机组件的 SWT UI 工具包采用)是要求客户端调用对象上的一个dispose
或destroy
方法。
您不太可能在每次运行 GC 时都释放内存。必须更有可能在运行 GC 时将内存释放给未使用的对象。
您可以通过提供一个包装器来实现这一点,该包装器具有用于释放资源的 finalize() 实现。当包装器被丢弃时,您可以清理资源。如果你真的希望它在每次 GC 上消失,你可以持有一个对包装器的 WeakReference。
顺便说一句,OpenJDK/Oracle HotSpot JVM 有另一种更轻量级的资源释放机制。这涉及使用未添加到终结队列中的 Cleaner 对象(这意味着可以更快地释放它)参见具有 Cleaner 的直接 ByteBuffer 作为示例。