20 Stimmen

Speicherleck bei der Verwendung von JNI zum Abrufen des Werts einer Zeichenkette aus Java-Code

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.

1voto

Cheung Punkte 174

Freigabe Array Objekt.

(*env)->DeleteLocalRef(env, array);

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X