studio programacion para móviles libro edición desarrollo desarrollar curso aprende aplicaciones java garbage-collection

java - para - manual de programacion android pdf



¿Por qué finaliza el no ser llamado? (5)

Tengo un par de preguntas con respecto al recolector de basura en java.

Q1.Por lo que entiendo, se llama a finalize () cuando el objeto está fuera del alcance y JVM está a punto de recoger basura. Pensé que el método finalize () es llamado automáticamente por el recolector de basura, pero parece que no funciona en este caso. ¿Cuál es la explicación? ¿Por qué es necesario que llame explícitamente el método finalize ()?

public class MultipleConstruct { int x,y; public MultipleConstruct(int x) { this.x= x; y=5; System.out.println("ONE"); } @Override protected void finalize() throws Throwable { // TODO Auto-generated method stub super.finalize(); System.out.println("FINALIZED"); } public static void main(String[] args) throws Throwable { MultipleConstruct construct = new MultipleConstruct(3); } }

Q2. Además, ¿cuándo se invoca el recolector de basura? Entiendo que gc es un hilo daemon e invocado por JVM, dependiendo del tamaño del montón restante. ¿Eso quiere decir que JVM espera que el programa use el límite de límite de recursos y luego notifique al gc para que barre los objetos de la basura?

EDITAR: ¿Cómo resolvió gc las referencias circulares?


El método finalize () se llama automáticamente durante la recolección de basura. El método System.gc () llama forzosamente al recolector de basura. pero tendremos que destruir el objeto antes. ejemplo:

public class Sample { public Sample() { System.out.println("Object created"); } @Override public void finalize() { System.out.println("Object Destroyed"); } public static void main(String args[]) { Sample x=new Sample(); Sample y=new Sample(); x=null; y=null; System.gc(); } }


Hay mucho para finalizar el método () que es francamente mucho para escribir, pero en resumen:

Un objeto está en el estado finalizado si aún no está disponible después de que se haya ejecutado su método de finalización, si lo hay. Un objeto finalizado está esperando la desasignación. Tenga en cuenta que la implementación de VM controla cuando se ejecuta el finalizador. Casi siempre es mejor que haga su propia limpieza en lugar de confiar en un finalizador. El uso de un finalizador también puede dejar recursos críticos que no se recuperarán durante un tiempo indeterminado.

En su caso, la razón por la que no se imprime es que no sabe cuándo el hilo del finalizador llamará al método finalize (). Lo que está sucediendo es que el programa está terminando antes de que cualquier cosa pueda imprimirse. Para verificarlo: edite el código dentro del código principal en (NOTA: esto no garantiza ni debería confiar en él, pero aún así imprime un tiempo)

for(int i =0;i<1000000;i++) { MultipleConstruct construct = new MultipleConstruct(3); construct = null; }

Hay muchas desventajas de utilizar un finalize () desde tomar más tiempo en la construcción de objetos hasta la posibilidad de pérdida de memoria y falta de memoria. Si se refiere fuertemente al mismo objeto dentro del finalize (), entonces nunca se llama por segunda vez y puede dejar el sistema en un estado no deseado, etc. etc. El único lugar donde debe usar finalize () es como una red de seguridad. para eliminar cualquier recurso como InputStream lo usa para cerrar (lo que tampoco garantiza que se ejecute cuando el programa aún esté activo). Otro lugar para usarlo es durante el uso de nativos donde el recolector de basura no tiene control.

Para más información, visite:

http://jatinpuri.com/?p=106


q1) se llama al método de finalización cuando el objeto se está recogiendo basura, por lo tanto, si no se está realizando un GC, es posible que no se llame al finalizador. Necesita llamar simplemente súper para preservar el comportamiento proporcionado por la implementación del Objeto.

q2) el momento exacto en que se realiza el GC depende de muchos factores como: qué JVM está usando, parámetros de ajuste, cantidad de montón libre, etc. Por lo tanto, no solo depende de un umbral de montón usado. También puede solicitar que se realice un GC a través de System.gc () pero no tiene garantía sobre si se ejecutará realmente y cuándo. Puede encontrar algunos detalles sobre cómo configurar GC en http://java.sun.com/performance/reference/whitepapers/tuning.html


se llama eventualmente o no se llama en absoluto

Básicamente, el GC escanea el montón de todo lo que no es alcanzable y ejecuta el finalizador en esos (después de lo cual necesita probar nuevamente que no es alcanzable para que se libere)

sin embargo, puede llevar un tiempo (efectivamente indefinido y realmente depende del comportamiento del programa) que el GC lo encuentre, por lo que no debe confiar en él para deshacerse de los datos críticos.

editar: en cuanto a referencias circulares, distingue entre objetos con un método de finalización y objetos sin uno

para que un objeto sea liberado (eliminado de la memoria principal) puede que no sea alcanzable por ningún código (esto incluye finalizadores que aún deben ejecutarse)

cuando 2 objetos con finalizadores son elegibles para ejecutar los finalizadores, el GC selecciona arbitrariamente un objeto y ejecuta el finalizador en él y luego puede ejecutar el otro objeto

tenga en cuenta que un finalizador puede ejecutarse mientras los campos de los objetos pueden o no estar finalizados


super.finalize();

debería ser lo último que llame