Ответ 1
ответ: _env->DeleteLocalRef(jBuff);
У меня есть метод Java, который обрабатывает растровое изображение и возвращает строку. Когда я вызываю этот метод из JNI (VS 2010), он работает, но если я вызову этот метод много раз, память о процессе, выросшем до краха. Инструкция, использующая много памяти:
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));
}
ответ: _env->DeleteLocalRef(jBuff);
Вы не вызывали DetachCurrentThread()
для каждого AttachCurrentThread()
, который запрашивается в Спецификация интерфейса Java Java. Это делает невозможным автоматическое освобождение локальных ссылок (jBuff
и str
). Кроме того, необходимо освободить const char*
, извлеченный через GetStringUTFChars()
.
Правильный способ - изменение
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;