2013-10-10 23 views
2

我有一个问题abour内存管理Java端口的OpenCV。OpenCV的Java JNIEXPORT内存管理

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 \模块\ java中\发生器\ SRC \ CPP \ Mat.cpp'。我的问题是关于以下部分:

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

它通过它铸造jlong返回垫对象的地址,不删除对象。那么,内存管理如何完成? Java是否运行垃圾收集器?或者有没有其他代码清除内存的C++方面?

回答

6

这里没有内存管理。

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

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

在Java Mat对象上,您必须调用release方法,该方法依次调用JNI函数。

finalize方法也调用n_delete它释放内存。

您可以看到Java代码here

+0

我知道这里没有做内存管理,我在问在哪里以及如何完成。 – guneykayim

+0

我在上面,两分钟。 – Geoffroy

+0

通过'new'分配的内存将保留在内存中,直到相应的'delete'调用。用jni,我会假定Java'dispose'或'finalize'会依次调用一个本地方法,传递要删除的jlong​​变量。 – Samhain

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; 

但是我还在l forward学习,OpenCV如何克服这个问题。

+1

使用'nullptr'而不是0来与指针进行比较。 – Geoffroy

+0

我已编辑帖子,现在很酷吗? – guneykayim