2

我对 OpenCV 的 java 端口的内存管理有疑问。

JNIEXPORT jlong JNICALL Java_org_opencv_core_Mat_n_1Mat__III
          (JNIEnv* env, jclass, jint rows, jint cols, jint type)
        {
            try {
                LOGD("Mat::n_1Mat__III()");

                Mat* _retval_ = new Mat( rows, cols, type );

                return (jlong) _retval_;
            } catch(cv::Exception e) {
                LOGD("Mat::n_1Mat__III() catched cv::Exception: %s", e.what());
                jclass je = env->FindClass("org/opencv/core/CvException");
                if(!je) je = env->FindClass("java/lang/Exception");
                env->ThrowNew(je, e.what());
                return 0;
            } catch (...) {
                LOGD("Mat::n_1Mat__III() catched unknown exception (...)");
                jclass je = env->FindClass("java/lang/Exception");
                env->ThrowNew(je, "Unknown exception in JNI code {Mat::n_1Mat__III()}");
                return 0;
            }
        }

此代码块取自“..\OpenCV-2.4.5\modules\java\generator\src\cpp\Mat.cpp”。我的问题是关于以下部分:

Mat* _retval_ = new Mat( rows, cols, type );
return (jlong) _retval_;

它通过强制转换来返回 mat 对象地址,jlong并且不会删除该对象。那么,内存管理是如何完成的呢?java是否运行垃圾收集器?或者 C++ 端是否还有其他代码可以以某种方式清除内存?

4

2 回答 2

6

这里没有进行内存管理。

该函数实际上返回一个指向堆分配对象的指针,而不关心内存管理。

实际上,这个方法对应于 Java 类org.opencv.core.Mat,它有一个名为 的长属性nativeObj。所以这个 java 类正在管理一个指针,它总是被传递给底层的 C++ 实现。

在 JavaMat对象上,您必须调用该release方法,该方法又调用 JNI 函数Java_org_opencv_core_Mat_n_release

finalize方法还调用n_deletewhich 释放内存。

您可以在此处查看 Java 代码。

于 2013-10-10T13:41:56.697 回答
4

好吧,我找不到答案,但我做了一个小把戏。我将成员变量定义为;

cv::Mat* mat = nullptr;

当我需要首先为新Mat对象分配内存时,我运行以下代码,然后进行内存分配。

if(mat != nullptr) // this is satisfied if memory is already allocated and not deleted
{
    delete mat;
    mat = nullptr;
}
mat = new cv::Mat(rows, cols, type);
return (jlong)mat;

但我仍然期待学习,OpenCV 如何克服这个问题。

于 2013-10-10T13:41:35.570 回答