2011-06-04 25 views
31

¿Debo liberar la cadena asignada después de pasarla al NewStringUTF()?NewStringUTF() y liberar memoria

que tienen algo de código similar a:

char* test; 
jstring j_test; 

test = some_function(); // <- malloc()s the memory 
j_test = (*env)->NewStringUTF(env, test); 

free(test); // <- should this be here? 

Cuando liberar la cadena después de pasarlo a NewStringUTF(), me sale un error de signal 11 (SIGSEGV), fault addr deadbaad. Si elimino la llamada free(), el error desaparece. ¿Qué estoy haciendo mal?

Veo opiniones contradictorias. Algunos dicen que debería liberarlo, algunos dicen que el VM lo libera, otros dicen que el VM no lo libera y que debes hacer magia vudú para liberarlo. Estoy confundido.

+0

posible duplicado de [JNI liberando memoria para evitar pérdida de memoria] (http://stackoverflow.com/questions/1533378/jni-freeing-memory-to-avoid-memory-leak) – NPE

Respuesta

61

El almacenamiento para el argumento const char* a NewStringUTF() es el único responsable: si asigna test con malloc(), entonces usted necesita para free() ella. Entonces, el fragmento que publicaste es correcto. Estás corrompiendo el montón en otro lado.

Veo opiniones contradictorias. Algunos dicen que yo debería liberarlo yo mismo, algunos dicen que la VM lo libera, algunos dicen que la VM no lo libera y debes hacer magia extraña de vudú para liberarlo. Estoy confundido.

Están hablando de la instancia jstring devuelta por NewStringUTF(). Eso sigue las reglas confusas para 'local references'.

Nunca es un error liberar esta referencia con DeleteLocalRef() cuando haya terminado con ella. Sin embargo, la JVM realiza alguna magia dudosa si llama al NewStringUTF() en el contexto de un hilo JVM. Cuando el método nativo vuelve a Java, cualquier referencia local filtrada se limpia automáticamente. Entonces, si está seguro de que su última llamada está en un hilo de Java, puede filtrar la referencia de manera segura.

Por otro lado, si se está ejecutando en el contexto de un hilo nativa - por ejemplo, algunos informes de eventos hilo hacer devoluciones de llamada a Java - nunca hay un retorno a Java, por lo que debe llamar DeleteLocalRef() a sí mismo en este jstring (y, de hecho, todas las demás referencias locales devueltas por llamadas JNI típicas).

+1

Interersting. Ahora sé dónde está mi problema. Necesito un jstring más persistente. Uno que se convierte en parte del recolector de basura y solo se limpia una vez que estoy realmente acabado. – Martin

+1

¿Alguna vez hay una situación en la que sea inseguro/incorrecto llamar a 'DeleteLocalRef()' en una 'jstring' obtenida con' NewStringUTF() '? – namuol

+0

@namuol si pasa jstring a Java más tarde, nunca debería eliminarlo ahora. –

4

Solo necesita DeleteLocalRef(), NewStringUTF() es solo una memoria malloc en JVM, que la JVM se encargará de la memoria.

Cuestiones relacionadas