I am using OpenCV with Java and because OpenCV has no idea about what the Java GC is doing, I have always been told that I need to release my Mat
objects using Mat.release()
to avoid memory leaks. Therefore, I have always been using try-finally:
// Suppose this is actually reading some image or similar
Mat mat = new Mat()
try {
// Do something with mat
} finally {
mat.release()
}
While debugging a memory leak (of which I have yet to find the cause), I had a look at the generated source code for Mat.java
and found the following:
public class Mat {
// ...
public void release() {
n_release(nativeObj);
}
// ...
@Override
protected void finalize() throws Throwable {
n_delete(nativeObj);
super.finalize();
}
// ...
So, in summary, release
internally calls n_release
and finalize
calls n_delete
. No matter the method called, after the method call, Mat.dataAddr()
returns 0L
either way.
My questions as a non-C++ developer are therefore the following:
n_release
and n_delete
?n_delete
actually free the memory associated with the Mat
or does it merely delete the pointer to it?Mat.release()
explicitly, or is a call to finalize()
(implicitly done by the garbage collector) enough?Edit:
While debugging my memory leak, I also had a look at Core.merge()
which looks like so:
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);
}
It creates a temporary Mat
object (called mv_mat
) on which it never calls release()
and because mv_mat
is internal to the method, no external caller can ever call mv_mat.release()
. I am therefore assuming that forgetting to call release()
while not being recommended (due to the reliance on finalizers) does not constitute a memory leak by itself.
Difference between n_release and n_delete: n_release decrements the reference count and frees the resource if no references remain. n_delete directly frees the memory when the Java object is garbage collected.
Does n_delete free memory?: Yes, n_delete is designed to free the allocated native memory, not just delete the pointer.
Need to call Mat.release() explicitly?: Yes, you should explicitly call Mat.release() to manage memory efficiently. Relying on finalize() is not advisable due to its unpredictable nature and potential for delayed resource release. Explicitly releasing resources with Mat.release() ensures timely memory management and avoids memory leaks.