我在Java中使用OpenCV,因为OpenCV不知道Java GC在做什么,所以我总是被告知我需要使用Mat.release()
释放我的Mat
个对象,以避免内存泄漏.因此,我一直在使用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()
(由垃圾收集器隐式完成)足够?
编辑:
在调试内存泄漏时,我也看了一下Core.merge()
,看起来像这样:
public static void merge(List<Mat> mv, Mat dst) {
Mat mv_mat = Converters.vector_Mat_to_Mat(mv);
merge_0(mv_mat.nativeObj, dst.nativeObj);
}
它创建了一个临时的Mat
对象(称为mv_mat
),它从不调用release()
,因为mv_mat
是方法的内部,所以没有外部调用者可以调用mv_mat.release()
.因此,我假设忘记调用release()
而不被推荐(由于依赖终结器)本身并不构成内存泄漏.