OpenCV JNI:Java/native对Mat的处理 – delete被调用两次的可能性?

huangapple go评论73阅读模式
英文:

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.

huangapple
  • 本文由 发表于 2020年9月7日 09:04:53
  • 转载请务必保留本文链接:https://go.coder-hub.com/63770231.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定