2012-02-20 24 views
10

tengo el siguiente método JNI que crea una colección de objetos Java de forma nativa, y luego devolverlos a Java:JNI objetos creación y gestión de memoria

JNIEXPORT jobject JNICALL Java_com_test_myClass_myMethod(JNIEnv * env, jclass klass) { 
    jclass arrayClass = env->FindClass("java/util/ArrayList"); 
    jmethodID initMethod = env->GetMethodID(arrayClass, "<init>", "()V"); 
    jmethodID addMethod = env->GetMethodID(arrayClass, "add", "(Ljava/lang/Object;)Z"); 
    jobject myArray = env->NewObject(arrayClass, initMethod); 

    env->CallBooleanMethod(myArray, addMethod, env->NewStringUTF("Hello")); 
    env->CallBooleanMethod(myArray, addMethod, env->NewStringUTF("World")); 

    return myArray; 
} 

¿Es necesario para liberar los objetos creados en el código nativo , o es hecho automáticamente por el GC? Si lo hago, ¿cómo hago eso, ya que necesito devolverlo a Java?

+0

Creo que correspondería al código nativo realizar su propia gestión de memoria. En este caso, me imagino que necesitaría agregar otro método nativo que libera los objetos asignados, a los que llama manualmente cuando termina con ellos. En términos más generales, si estás haciendo cosas con JNI, entonces espero que estés preparado para un mundo de dolor. Esta respuesta puede ayudar: http://stackoverflow.com/questions/214699/jni-memory-management-using-the-invocation-api – aroth

+3

@aroth - wrong. si asigna objetos Java en JNI, son objetos Java, propiedad del GC. – bmargulies

+0

@bmargulies - Tiene sentido, pero ¿qué ocurre con el código nativo que asigna objetos/memoria que no son Java, por ejemplo al invocar 'malloc()'? – aroth

Respuesta

11

No necesita liberar los objetos Java creados en el código nativo. De hecho, no puedes. El recolector de basura puede liberar el objeto cuando no quedan más referencias.

De vez en cuando es útil en el código nativo para liberar referencias a objetos Java. Esto puede reducir los requisitos de memoria cuando el código nativo tiene, pero ya no necesita, referencias a objetos grandes o un gran número de referencias.

De: "Referencias globales y locales" en el JNI specification.

En la mayoría de los casos, el programador debe confiar en la máquina virtual para liberar todas las referencias locales después de que regrese el método nativo. Sin embargo, hay ocasiones en que el programador debe liberar explícitamente una referencia local. Considere, por ejemplo, las siguientes situaciones:

  • Un método nativo accede a un gran objeto Java, creando así una referencia local al objeto Java. El método nativo luego realiza cálculos adicionales antes de regresar a la persona que llama. La referencia local al objeto Java grande evitará que el objeto sea recolectado como basura, incluso si el objeto ya no se usa en el resto del cálculo.
  • Un método nativo crea una gran cantidad de referencias locales, aunque no todas se utilizan al mismo tiempo. Dado que la VM necesita una cierta cantidad de espacio para realizar un seguimiento de una referencia local, crear demasiadas referencias locales puede hacer que el sistema se quede sin memoria. Por ejemplo, un método nativo recorre una gran variedad de objetos, recupera los elementos como referencias locales y opera en un elemento en cada iteración. Después de cada iteración, el programador ya no necesita la referencia local al elemento de la matriz. Se proporcionó

detalle adicional Ver "Freeing References" en la Guía del Programador de JNI.

+0

Leí la guía sobre Liberación de referencias, pero tengo una pregunta al respecto: ¿Podría crear un problema de agotamiento de recursos al llamar al método en mi publicación inicial una gran cantidad de veces? En caso afirmativo, ¿dónde puedo liberar las referencias, ya que aún tengo que devolverlas? – nbarraille

+0

Las referencias locales se liberan automáticamente después de cada llamada. No tiene que hacerlo explícitamente, a menos que 1) haya creado una referencia global, o 2) necesite liberar referencias locales antes de que se complete la llamada, por una razón que se describe en el enlace. La referencia que está devolviendo se está copiando.Tanto myArray como la referencia devuelta apuntan al mismo objeto Java. –

+0

el enlace está muerto ... – BeniBela

Cuestiones relacionadas