OpenCV Java JNIEXPORT内存管理

时间:2013-10-10 12:57:52

标签: java c++ opencv java-native-interface

我对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 ++方面还有其他代码以某种方式清除内存吗?

2 个答案:

答案 0 :(得分:6)

此处没有内存管理。

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

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

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

finalize方法也会调用释放内存的n_delete

您可以看到Java代码here

答案 1 :(得分: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如何克服这个问题。