2011-06-04 18 views
31

Devo liberare la stringa assegnata dopo averla passata a NewStringUTF()?NewStringUTF() e liberare memoria

ho qualche codice simile 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? 

Quando ho liberare la stringa dopo aver superato a NewStringUTF(), ricevo un errore signal 11 (SIGSEGV), fault addr deadbaad. Se rimuovo la chiamata free(), l'errore si annulla. Che cosa sto facendo di sbagliato?

Vedo opinioni contrastanti. Alcuni dicono che dovrei liberarlo da solo, alcuni dicono che la VM lo libera, alcuni dicono che la VM non la libera e dovresti fare una strana magia voodoo per liberarla. Non ho capito bene.

+0

possibile duplicato di [JNI Freeing Memory per evitare perdite di memoria] (http://stackoverflow.com/questions/1533378/jni-freeing-memory-to-avoid-memory-leak) – NPE

risposta

61

L'archiviazione per il const char* argomento per NewStringUTF() è interamente la vostra responsabilità: se assegnato test con malloc(), allora avete bisogno di free() esso. Quindi, lo snippet che hai postato è corretto. Stai corrompendo l'heap da qualche altra parte.

Vedo opinioni contrastanti. Alcuni dicono che I dovrebbe liberarlo da solo, alcuni dicono che la VM lo libera, alcuni dicono che la VM non libera e dovresti fare la strana magia voodoo per liberarla. Non ho capito bene.

Si tratta dell'istanza jstring restituita da NewStringUTF(). Ciò segue le regole confuse per 'local references'.

Non è mai un errore rilasciare questo riferimento con DeleteLocalRef() quando si è finito con esso. Tuttavia, la JVM esegue una magia dubbia se si chiama NewStringUTF() nel contesto di un thread JVM. Quando il metodo nativo ritorna a Java, qualsiasi riferimento locale trapelato viene automaticamente ripulito. Quindi, se sei sicuro che il tuo ultimo chiamante è in una discussione Java, puoi tranquillamente perdere il riferimento.

D'altra parte, se si esegue nel contesto di un thread nativo - per esempio, un evento di segnalazione filo rendendo callback a Java - non c'è mai è un ritorno a Java, quindi è necessario chiamare DeleteLocalRef() te su questo jstring (e in effetti tutti gli altri riferimenti locali restituiti dalle tipiche chiamate JNI).

+1

Interersting. Ora so dov'è il mio problema. Ho bisogno di un jstring più persistente. Uno che diventa parte del garbage collector e viene pulito solo una volta che ho finito. – Martin

+1

C'è mai una situazione in cui non è sicuro/errato chiamare 'DeleteLocalRef()' su un 'jstring' ottenuto con' NewStringUTF() '? – namuol

+0

@namuol se passi jstring a java in seguito, non dovresti mai cancellarlo ora. –

4

Hai solo bisogno di DeleteLocalRef(), NewStringUTF() è solo memoria malloc su JVM, che la JVM si prenderà cura della memoria.

Problemi correlati