2013-10-10 2 views
2

У меня вопрос о правильном управлении памятью порта Java OpenCV.Управление памятью Java JNIEXPORT OpenCV

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 \ Генератор \ 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

C++ выделенная память через '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; 

Но я все еще хочу узнать, как OpenCV преодолевает эту проблему.

+1

Использовать 'nullptr' вместо 0 для сравнения с указателями. – Geoffroy

+0

Я отредактировал сообщение, сейчас круто? – guneykayim

Смежные вопросы