2013-10-10 21 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