2011-07-26 10 views
5

Cuando alguien está haciendo enlaces de una biblioteca C a Java (o cualquier otro lenguaje recogido de basura sin destructores que se garantiza que se ejecutan), ¿cómo se ocupan de la desasignación correcta de la memoria no recolectada en la basura?Vinculaciones etiquetadas que implican memoria no sincronizada para idiomas sin destructores garantizados?

EDIT: Lo que estoy pensando (sé que esto no está explícitamente en mi pregunta original) es cuando una pieza de memoria no grabada contiene referencias a otros recursos no gc que necesitan para ser liberado cuando ese objeto es liberado. Por ejemplo, si tiene un nodo de lista vinculada no-gc que encabeza una larga lista de tales nodos y desea que el sistema gc lo limpie automáticamente, ¿cómo se configura?

+0

posible duplicado de [¿Hay un destructor para Java?] (Http://stackoverflow.com/questions/171952/is-there-a-destructor-for-java) – Raedwald

Respuesta

2

En java, tiene el concepto finalize(). Puedes liberar la memoria C allí.

Sin embargo, probablemente una mejor manera es usar PhantomReferences junto con ReferenceQueue. Puede ampliar la clase PhantomReference para que contenga alguna identificación o puntero o lo que sea para la memoria del lado C que necesita liberar. Cuando se pone en cola en la ReferenceQueue, puede liberar la memoria del lado C a la que apunta este ID: se garantiza que el objeto Java ya no existe "en Java".

+0

Cambiaron el aspecto de las páginas de javadoc. – compman

+1

¿Está garantizado que se ejecutará finalize() de Java antes de liberar un objeto Java (si es que alguna vez lo es)? – compman

+0

"El contrato general de finalización es que se invoca siempre y cuando la máquina virtual JavaTM haya determinado que ya no hay ningún medio por el cual se pueda acceder a este objeto por un hilo que aún no ha muerto, excepto como resultado de un acción tomada por la finalización de algún otro objeto o clase que esté listo para ser finalizado. El método de finalización puede tomar cualquier medida, incluyendo hacer que este objeto esté disponible nuevamente para otros hilos; el propósito habitual de finalizar, sin embargo, es realizar acciones de limpieza antes el objeto se descarta irrevocablemente ". – stolsvik

0

Al usar enlaces con idiomas como Java, la máquina de otro idioma contiene contadores de referencia para cada objeto asignado. La API debe dar métodos para aumentar o disminuir estos contadores para indicar que la máquina que su programa C contiene referencia a los otros objetos de la máquina. Si el programa C no tiene referencias a un objeto dado, el contador de referencia puede llegar a 0 y la máquina de otro idioma será libre de recolectarlo. Sin embargo, es posible que no pueda pedirle a la máquina que libere un objeto determinado.

2

Normalmente proporcionan API para crear y publicar una referencia.

Por ejemplo, interfaz nativa de Java proporciona referencias globales que permite el fijar un objeto de Java en la memoria hasta que el programa C se hace con él a través NewGlobalRef y DeleteGlobalRef

NewGlobalRef Crea una nueva referencia mundial para el objeto a que se refiere por el argumento obj. El argumento obj puede ser una referencia global o local. referencias globales, deben eliminarse de forma explícita de llamando DeleteGlobalRef()

y también proporciona referencias locales que sólo duran tanto como Java ha entregado el control a C para:

referencias locales son válidos para la duración de una llamada de método nativo. Se liberan automáticamente después de que el método nativo regrese.

El JVM embedding API proporciona un mecanismo similar que permite fijar un objeto en la memoria hasta que el programa C determina que se ha terminado con él.

Python's C extension API proporciona una API similar a la JNI.

Una referencia prestada se puede cambiar a una referencia de propiedad llamando al Py_INCREF().

El propietario de una referencia es responsable de llamar al Py_DECREF() cuando la referencia ya no es necesaria.

Los nombres pitón reflejan el hecho de que Python usa el recuento de referencias * pero el API es básicamente el mismo que el de JNI que se basa en un conteo colector de basura no-ref - que tiene una función que los pasadores de una región de memoria administrada por el intérprete y otra que libera una región anteriormente anclada al intérprete.

* - python no es un verdadero enfoque de recuento de ref.Desde la misma página "Si bien Python usa la implementación tradicional de recuento de referencias, también ofrece un detector de ciclos que funciona para detectar ciclos de referencia".

Cuestiones relacionadas