Ich verwende GetStringUTFChars, um den Wert einer Zeichenfolge aus dem Java-Code mit JNI abzurufen und die Zeichenfolge mit ReleaseStringUTFChars freizugeben. Wenn der Code unter JRE 1.4 ausgeführt wird, gibt es kein Speicherleck, aber wenn derselbe Code mit einer JRE 1.5 oder einer höheren Version ausgeführt wird, steigt der Speicherbedarf. Dies ist ein Teil des Codes
msg_id=(*env)->GetStringUTFChars(env, msgid,NULL);
opcdata_set_str(opc_msg_id, OPCDATA_MSGID, msg_id);
(*env)->ReleaseStringUTFChars(env, msgid,msg_id);
Ich verstehe den Grund für das Leck nicht, kann mir jemand helfen?
Wenn ich den Rest des Codes auskommentiere, aber diesen Teil stehen lasse, kommt es zu einem Speicherverlust. Dies ist ein Teil des Codes, den ich verwende
JNIEXPORT jobjectArray JNICALL Java_msiAPI_msiAPI_msgtoescalate( JNIEnv *env,
jobject job,
jstring msgid,
jlong msgseverity,
jstring msgprefixtext,
jint flag )
{
opcdata opc_msg_id; /* data struct to store a mesg ID */
const char *msg_id;
int ret, ret2;
jint val;
val=67;
jstring str=NULL;
jobjectArray array = NULL;
jclass sclass=NULL;
/* create an opc_data structure to store message ids of */
/* messages to escalate */
if ((ret2=opcdata_create(OPCDTYPE_MESSAGE_ID, &opc_msg_id))!= OPC_ERR_OK)
{
fprintf(stderr, "Can't create opc_data structure to store message. opcdata_create()=%d\n", ret2);
cleanup_all();
}
//////////////////////////////////////////////////////////
msg_id=(*env)->GetStringUTFChars(env,msgid,NULL);
opcdata_set_str(opc_msg_id, OPCDATA_MSGID, msg_id);
(*env)->ReleaseStringUTFChars(env, msgid, msg_id);
ret=opcmsg_ack(connection,opc_msg_id);
//////////////////////////////////////////////////////////
if(flag==0 && ret==0)
{
sclass = (*env)->FindClass(env, "java/lang/String");
array = (*env)->NewObjectArray(env, 2, sclass, NULL);
str=(*env)->NewStringUTF(env,"0");
(*env)->SetObjectArrayElement(env,array,0,str);
(*env)->DeleteLocalRef(env, str);
str=(*env)->NewStringUTF(env,"0");
(*env)->SetObjectArrayElement(env,array,1,str);
(*env)->DeleteLocalRef(env, str);
}
opcdata_free(&opc_msg_id);
if(ret!=0)
return NULL;
else
return(array);
}
Im obigen Beispiel sehe ich kein Speicherleck, wenn ich die Abschnitte zwischen ///// kommentiere.
5 Stimmen
Das scheint in Ordnung zu sein. Woher wissen Sie, dass dies die Ursache für Ihr Leck ist?
5 Stimmen
Ich stimme fd zu - bitte geben Sie an, woher Sie wissen, dass dies das Leck ist. Haben Sie Profiler-Daten, die dies anzeigen?
7 Stimmen
Es könnte sein, dass die freigegebene Zeichenfolge nicht sofort in den Müll wandert. Daher beobachten Sie einen Anstieg der Speichernutzung. Sie könnten auch versuchen, nur den opcdata_set_str()- oder opcmsg_ack()-Aufruf auszukommentieren und überprüfen, ob er immer noch Speicher leckt.
3 Stimmen
Wie lautet der Prototyp (Deklaration) für die Funktion opcdata_set_str, bitte?
2 Stimmen
... und was macht es? Ich würde sagen, das Leck befindet sich innerhalb dieser Funktion. Gibt es eine ergänzende Aktion, die Sie ergreifen sollen, um das Datenelement freizugeben?
1 Stimmen
Womit messen Sie die Speichernutzung? Lecken Sie den Java-Heap oder den nativen Heap?