2011-12-20 16 views
10

Mam metodę Java, która przetwarza bitmapę i zwraca ciąg. Kiedy nazywam tę metodę z JNI (VS 2010), działa, ale jeśli wielokrotnie tę metodę nazywam, pamięć procesu będzie rosła aż do awarii. Dyspozycja, które używają dużo pamięci jest:JNI NewByteArray przeciek pamięci

jbyteArray jBuff = _env->NewByteArray(b->Length); 

Mój kod:

static jobject staticArray=0; 

System::String^ MyClass::ExecuteJavaMethod(System::Drawing::Bitmap^ bmp) 
{ 
    JNIEnv *_env; 
    System::String^ out; 
    unsigned const char * buff; 

    int res = jvm->AttachCurrentThread((void **)&_env, NULL); 

    if (jvm->GetEnv((void**) &_env, JNI_VERSION_1_6) != JNI_OK) 
    { 
     return "GetEnv ERROR"; 
    } 

    //save the bitmap in the stream 
    MemoryStream^ ms = gcnew MemoryStream(); 
    bmp->Save(ms, ImageFormat::Bmp); 

    //get the bitmap buffer 
    array<unsigned char>^b = ms->GetBuffer() ; 

    //unmanaged conversion 
    buff = GetUnmanaged(b,b->Length); 


    //fill the buffer 
    jbyteArray jBuff = _env->NewByteArray(b->Length);  
    _env->SetByteArrayRegion(jBuff, 0, b->Length, (jbyte*) buff); 

    //call the java method 
    jstring str = (jstring) _env->CallStaticObjectMethod ( Main, 
           javaMethod, 
           jBuff); 



    // _env->ReleaseByteArrayElements(jBuff,(jbyte*)buff), 0); //NOT WORKING 

    //staticArray= _env->NewGlobalRef(jBuff); NOT 
    //_env->DeleteLocalRef(jBuff);    WORKING 


    //return the string result of the java method 
    return gcnew String(env->GetStringUTFChars(str, 0)); 

} 
+0

Dlaczego wypowiedzieć swoją linię, która robi '_ReleaseByteArrayElements()'? – fge

+0

ponieważ jest taka sama, pamięć rośnie i się zawiesza ... – Riccardo

+0

Wydaje się, że nie wydajesz "buff" w żadnym momencie. Czy "GetUnmanaged" przydziela tymczasowy bufor, który nigdy nie zostanie odzyskany? –

Odpowiedz

17

odpowiedź brzmi: _env->DeleteLocalRef(jBuff);

0

Nie zadzwoniłeś DetachCurrentThread() dla każdego AttachCurrentThread(), który jest wymagany w Java Native Interface Specification. Dzięki temu lokalne odwołania (jBuff i str) nie mogą zostać automatycznie zwolnione. Ponadto należy zwolnić const char*, który należy pobrać przez GetStringUTFChars().

Poprawny sposób to zmienić

return gcnew String(env->GetStringUTFChars(str, 0)); 

do

const char* cstr = env->GetStringUTFChars(str, 0); 
System::String^ retstr = gcnew String(cstr); 
env->ReleaseStringUTFChars(str, cstr); 
jvm->DetachCurrentThread(); 
return retstr; 
Powiązane problemy