2011-12-20 41 views
10

我有一個處理位圖並返回String的Java方法。 當我從JNI(VS 2010)調用此方法時,它可以工作,但如果我多次調用此方法,則該進程的內存會長大直到崩潰。 使用大量內存的指令是:JNI NewByteArray內存泄漏

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

我的代碼:

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

爲什麼你對此有何評論你的線,不'_ReleaseByteArrayElements()'? – fge 2011-12-20 11:18:30

+0

因爲是一樣的,內存上升和崩潰... – Riccardo 2011-12-20 11:27:27

+0

你似乎不會在任何時候釋放'buff'。 GetUnmanaged是否分配一個永不被回收的臨時緩衝區? – 2011-12-20 23:20:29

回答

17

的答案是:_env->DeleteLocalRef(jBuff);

0

你沒有打電話給DetachCurrentThread()每個AttachCurrentThread(),被請求在Java Native Interface Specification。這使得本地引用(jBuffstr)無法自動釋放。此外,需要發佈通過GetStringUTFChars()獲取的const char*

正確的方法是改變

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

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