我对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 ++方面还有其他代码以某种方式清除内存吗?
答案 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如何克服这个问题。