英文:
OpenCV JNI: Java/native handling of Mat - possibility for delete getting called twice?
问题
我正在处理一个项目,在该项目中,我有一个在本机代码中(根据一些Java代码的请求)在堆上分配的Mat,如下所示:
Mat* mat = new Mat(height, width, type, pointer_to_some_native_data_buffer);
然后我在Java中创建一个Mat对象,并通过使用从本机代码返回的指针将其指向该本机Mat:
Mat javaHandleToNativeMat = new Mat(pointerFromNativeCode);
在从Java端对其进行一些处理之后,我调用一个本机方法来释放最初分配的Mat:
delete (Mat*) ptr;
我的问题是,当GC运行Java Mat的终结器方法时,指向本机Mat的Java Mat上可能发生本机内存损坏吗?
终结器代码如下:
@Override
protected void finalize() throws Throwable {
n_delete(nativeObj);
super.finalize();
}
请注意,它调用了 n_delete(nativeObj)
。我想知道这是否可能是一个问题,因为我之前在本机代码中已经删除了该对象。如果是问题,最佳解决方法是什么?我是否应该简单地在本机Mat上调用 release()
方法,并允许在GC运行时在终结器中实际删除它?
英文:
I'm working on a project where I have a Mat that is allocated on the heap in native code (at the request of some Java code), like so:
Mat* mat = new Mat(height, width, type, pointer_to_some_native_data_buffer);
I then create a Mat object in Java, and point it to that native Mat by using a pointer returned from native code:
Mat javaHandleToNativeMat = new Mat(pointerFromNativeCode);
After doing some processing on it from the Java side, I call a native method to free the Mat that was allocated at the beginning:
delete (Mat*) ptr;
My question is, could native memory corruption happen when the GC runs the finalizer method on the Java Mat that pointed to the native Mat?
The finalizer code is as follows:
@Override
protected void finalize() throws Throwable {
n_delete(nativeObj);
super.finalize();
}
Notice that it calls n_delete(nativeObj)
. I'm wondering if this could be a problem, since I previously deleted the object in native code. If it is a problem, what is the best way to fix the problem? Should I simply call release()
on the native Mat, and allow it to actually be deleted in the finalizer when the GC runs?
答案1
得分: 1
因为您正在删除原生的 Mat
,并且 n_delete
的实现如下:
JNIEXPORT void JNICALL Java_org_opencv_core_Mat_n_1delete
(JNIEnv*, jclass, jlong self)
{
delete (Mat*) self;
}
所以 GC 会导致对 cv::Mat
指针进行两次删除,这是错误的。您可以在这里找到关于两次删除指针的更详细描述。
英文:
Since you're deleting the native Mat
and the implementation of n_delete
is:
JNIEXPORT void JNICALL Java_org_opencv_core_Mat_n_1delete
(JNIEnv*, jclass, jlong self)
{
delete (Mat*) self;
}
the GC will delete the cv::Mat
pointer twice, which is BAD. You can find here a more in depth description on what deleting a pointer twice implies.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论