Рассмотрим следующие сегменты кода C.
Сегмент 1:
char * getSomeString(JNIEnv *env, jstring jstr) {
char * retString;
retString = (*env)->GetStringUTFChars(env, jstr, NULL);
return retString;
}
void useSomeString(JNIEnv *env, jobject jobj, char *mName) {
jclass cl = (*env)->GetObjectClass(env, jobj);
jmethodId mId = (*env)->GetMethodID(env, cl, mName, "()Ljava/lang/String;");
jstring jstr = (*env)->CallObjectMethod(env, obj, id, NULL);
char * myString = getSomeString(env, jstr);
/* ... use myString without modifing it */
free(myString);
}
Поскольку myString освобождается в useSomeString, я не думаю, что создаю утечку памяти; Однако я не уверен. Спецификация JNI специально требует использования ReleaseStringUTFChars. Поскольку я получаю указатель char * в стиле C от GetStringUTFChars, я полагаю, что ссылка на память существует в стеке C, а не в куче JAVA, поэтому она не находится в опасности сбора мусора; однако я не уверен.
Я знаю, что изменение getSomeString следующим образом будет безопаснее (и, вероятно, предпочтительнее).
Сегмент 2:
char * getSomeString(JNIEnv *env, jstring jstr) {
char * retString;
char * intermedString;
intermedString = (*env)->GetStringUTFChars(env, jstr, NULL);
retString = strdup(intermedString);
(*env)->ReleaseStringUTFChars(env, jstr, intermedString);
return retString;
}
Из-за нашего «процесса» мне нужно построить аргумент о том, почему getSomeString в Сегменте 2 предпочтительнее Сегмента 1.
Кто-нибудь знает о какой-либо документации или ссылках, в которых подробно описывается поведение GetStringUTFChars и ReleaseStringUTFChars в зависимости от того, где выделена память или что (если есть) выполняется дополнительная бухгалтерия (т. Е. Указатель локальной ссылки на создаваемую кучу Java и т. Д.) , Каковы конкретные последствия игнорирования этой бухгалтерии.
Заранее спасибо.