2010-10-11 10 views
5

Estoy usando la API de invocación JNI, que inicia una JVM dentro de un programa C; en esta situación, obtienes un puntero JNIEnv que sigue siendo válido hasta que destruyas explícitamente la JVM. ¿La distinción local/global todavía se aplica aquí? ¿Cuál es el significado de una referencia local a un objeto recién creado, ya que el JNIEnv permanece en el alcance todo el tiempo?Referencias de objeto JNI obtenidas a través de la API de invocación: ¿local o global?

Respuesta

6

El libro JNI es un poco escueta acerca de esta situación, pero puedes averiguarlo si lo estudias lo suficiente. Básicamente, cuando adjunta un hilo de C nativo a la JVM, crea un contexto local que puede almacenar algunas referencias locales.

Estas referencias locales serán nunca liberadas hasta que las libere manualmente con DeleteLocalRef, o destruya el contexto local llamando a DetachThread. Debido a que probablemente no esté conectando y desconectando muchas JVM, es muy importante que llame a DeleteLocalRef en cada referencia local que cree.

La siguiente pregunta natural es "¿por qué crear refs globales en absoluto, si los refs locales no reciben GC'ed hasta que la JVM se separe?" Bueno, las referencias locales no se pueden compartir entre hilos. Por lo tanto, aún debe crear referencias globales para hacer eso.

+0

+1: Esta es la mejor respuesta aquí. –

+0

Ahora que tengo más experiencia en JNI, estoy de acuerdo en que esta es la respuesta más clara. – Flavio

+1

El comentario sobre los refs locales que nunca se liberan muestra la sutileza de utilizar JNI: si convierte una referencia local en una referencia global, asegúrese de eliminar la referencia local más adelante. De lo contrario, la referencia local no se eliminará y tendrá una pérdida de memoria. –

1

Creo que el hilo que creó JVM se convierte en hilo de Java, que, como cualquier hilo creado en Java, o conectado a través de AttachCurrentThread(), tiene su marco de pila local. Por lo tanto, cualquier objeto que cree se convierte en una referencia local en este marco de pila, que caducará cuando destruya JVM (no puede separar el hilo principal) o llame a DeleteLocalRef().

+0

¿Tiene alguna referencia de documentación sobre esto? ¿Y es legal pasar tales referencias locales a otros JNIEnv obtenidos cuando Java realiza una llamada C nativa? – Flavio

1

Probablemente una llamada DettachCurrentThread() libera las referencias también. Desafortunadamente la especificación JNI no define claramente el comportamiento de las referencias de la API de invocación, y puede ser que la semántica reales dependerán de la aplicación específica JVM: S

Cuestiones relacionadas