我将 OpenCV 与 Java 结合使用,因为 OpenCV 不知道 Java GC 在做什么,所以我总是被告知需要使用
Mat
释放我的 Mat.release()
对象以避免内存泄漏。因此,我一直在使用try-finally:
// Suppose this is actually reading some image or similar
Mat mat = new Mat()
try {
// Do something with mat
} finally {
mat.release()
}
在调试内存泄漏时(我还没有找到原因),我查看了
Mat.java
生成的源代码,发现了以下内容:
public class Mat {
// ...
public void release() {
n_release(nativeObj);
}
// ...
@Override
protected void finalize() throws Throwable {
n_delete(nativeObj);
super.finalize();
}
// ...
因此,总而言之,
release
内部调用n_release
,finalize
调用n_delete
。无论调用哪个方法,在方法调用之后,Mat.dataAddr()
都会返回0L
。
作为一名非 C++ 开发人员,我的问题如下:
n_release
和 n_delete
有什么区别?n_delete
实际上释放了与Mat
相关的内存还是仅仅删除了指向它的指针?Mat.release()
还是调用 finalize()
(由垃圾收集器隐式完成)就足够了?n_release 和 n_delete 的区别: n_release 减少引用计数并在没有引用剩余时释放资源。 n_delete 在Java对象被垃圾回收时直接释放内存。
n_delete是否释放内存?: 是的,n_delete 的目的是释放分配的本机内存,而不仅仅是删除指针。
需要显式调用 Mat.release() 吗?: 是的,您应该显式调用 Mat.release() 来有效管理内存。不建议依赖 Finalize(),因为它的不可预测性和延迟资源释放的可能性。使用 Mat.release() 显式释放资源可确保及时的内存管理并避免内存泄漏。