Vous êtes sur la page 1sur 4

Pablo Estuardo Medrano Velasquez 201222552

Garbage Collector

Que es el Garbage Collector? El garbage collector de Java provee una solucin automtica a la gestin de memoria. En la mayoria de los casos el proceso de liberar memoria debe de pertenecer a la lgica de las aplicaciones desarrolladas. Esto es tipico para la memoria que ha sido usada para crear apilamientos (pilas heap) en Java, estos casos se puede ver en constantes para gestin de pools y en las reas de los mtodos. La pila (heap) es un parte de la memoria donde los objetos de java viven, y esta es la unica parte de la memoria que es de alguna manera involucrados en el proceso de recoleccin del garbage collector. Todo el garbage collector gira entorno a asegurar que la pila (heap) de memoria siempre este liberando espacio tanto como sea posible. El prposito del garbage collector es encontrar y eliminar objetos que no puedan ser alcanzados.

Cuando se inicia el Garbage Collector? La gestin del garbage collector esta a cargo de la JVM ( Java Virtual Machine) , la experiencia indica que cuando los programas en Java hace una peticin al garbage collector, la JVM suele conceder dicha peticin a ser atendida en una manera temprana, pero no se garantia que esto se cumpla. Por lo general se dice que el Garbage Collector, piensa por si solo y se ejecuta cuando el lo desea. Cmo funciona el GC? No podemos estar seguros. Podemos haber escuchado que el GC usa un algoritmo de marca y barrido, y para cualquier implementacin de Java dada esto puede ser verdad, pero la especificacin de Java no garantiza cualquier implementacin particular. Podemos haber oido que el GC usa un contador de referencia; una vez mas puede ser o no puede ser. El concepto importante es entender cuando un objeto se convierte en elegible para el GC. Para responder a esto deberemos dar un salto y hablar un poco sobre los Threads. Los programas en Java, tienen desde uno hasta varios threads (hilos). Cada thread tiene su propio stack de ejecucin. normalmente, el programador hace que se ejecute un hilo en Java, el que usa el mtodo main(). Hay mas razones por las que se puede lanzar threads adicionales desde neustro thread principal. En adicin a tener su propio stack de ejecucin, cada thread tiene su propio ciclo de vida. Por ahora, todo lo que necesitamos saber es que los threads pueden estar vivos o muertos. Con esta informacin de fondo, podemos decir con claridad que un objeto es elegible para el GC cuando ningn thread vivo puede acceder a el. Basados en esta definicin, el GC hace algo mgico, operaciones desconocidas, y cuando descubre un objeto que no puede ser alcanzado por cualquier thread vivo, se considera que el objeto es elegible para el borrado. Cuando hablamos sobre alcanzar un objeto, estamos hablando realmente sobre tener al alcance su variable de referencia que refiere al objeto en cuestin. Si nuestro programa Java tiene una variable de referencia que se refiere a un objeto, y esa variable de referencia est disponible en un thread vivo, entonces el objeto es considerado alcanzable. Hablaremos mas sobre como los objetos pueden ser inalcanzables en la siguiente seccin. Puede una aplicacin Java quedarse sin memoria? Si. El sistema de recoleccin de basura intenta eliminar objetos de la memoria cuando no son usados. Sin embargo, si mantenemos muchos objetos viviendo el sistema puede quedarse sin memoria. La recoleccin de basura no puede asegurar que haya

Pablo Estuardo Medrano Velasquez 201222552


suficiente memoria, solo que la memoria que est disponible pueda ser administrada de la manera mas eficiente como sea posible.

Como trabaja el Garbage Collector? Cada programa hecho en Java tiene uno o ms hilos, donde cada uno de estos es dueo de su parte en la pila de la memoria. Un objeto es elegible por el garbage collector, cuando no se pueda acceder a l (a travs de su hilo), esto es que no tiene una variable de referencia accesible que apunte al objeto en cuestin. El garbage collector no puede asegurar que siempre haya suficiente memoria, solo que la memoria que existe sera gestionada lo ms eficientemente posible. Ejemplos de llamadas explicitas para el Garbage Collector: Estas llamadas o preparaciones de objetos para el garbage collector no garantizan su ejecucin, ya que tal y como se comento anteriormente el depende de la JVM y es controlado por el Runtime. Cmo sabe el Garbage Collector lo que puede borrar y lo que no? Es algo muy simple, si un objeto no tiene referencias desde el Stack tiene que ser eliminado. La magia de este recolector de basura deja asombrados a los programadores que odian tener que gestionar la memoria ellos mismos, y es que es algo muy til, pero se trata de un arma de doble filo. Entre sus contras tenemos que al tratarse de un proceso de prioridad baja, es poco probable que se ejecute cuando se est haciendo un uso intensivo de la CPU. Esto se puede solucionar si se solicita una pasada del Garbage Collector desde el propio cdigo. No se tiene que abusar de ello, pero puede resultar interesante tras una serie de operaciones que se sepa a ciencia cierta que puede dejar objetos sin referencias. El mtodo de solicitar esta pasada se muestra en las siguientes lineas. 1public void pasarGarbageCollector(){ 2 3 Runtime garbage = Runtime.getRuntime(); 4 garbage.gc(); 5 6} El cdigo que se muestra a continuacin es un mtodo de probar que esto efectivamente ayuda a liberar la memoria. Se realiza un bucle en el que se generan referencias y se eliminan las mismas y al terminar se solicita a la JVM que elimine todo objeto no referenciado. Tambin se muestran por consola la memoria libre que se tena antes y despus de la peticin. 1 class TestRecolector{ 2 3 public static void main(String[] args){ 4 5 TestRecolector test = new TestRecolector(); 6 test.testear(); 7 8 } 9 public void testear(){ 10 Date fecha = null;

Pablo Estuardo Medrano Velasquez 201222552


11 for (int i = 0; i<99999999;i++){ 12 fecha = new Date(2011,8,7); 13 fecha = null; 14 } 15 16 this.pasarGarbageCollector(); 17 } 18 public void pasarGarbageCollector(){ 19 20 Runtime garbage = Runtime.getRuntime(); 21 System.out.println("Memoria libre antes de limpieza: "+ garbage.freememory()); 22 23 garbage.gc(); 24 25 System.out.println("Memoria libre tras la limpieza: "+ garbage.freememory()); 26 } 27} En muchas ocasiones, al hacer operaciones, especialmente al trabajar con ArrayList u otras listas, acostumbramos a emplear una variable temporal que solo resulta til durante el tiempo de ejecucin de esa operacin. Cuando estas operaciones se hacen en un mtodo externo al hilo principal no hay problema, pues sus residuos sern limpiados al salir del mtodo, pero si por alguna razn se realizan en el hilo principal, o en un mtodo que rena mltiples operaciones (y que est largo rato ejecutndose), sera una buena idea que al terminar con el bucle se le asignara el valo r null a esas variables para dejar claro al Garbage Collector que ya no nos interesa mantenerla en memoria. EL MTODO finalize() El otro problema que supone el paso automtico o descontrolado del Garbage Collector es que puede eliminar un objetos con informacin que queramos guardar y que igual se ha quedado sin referencia por culpa nuestra. Por suerte, todas las clases heredan de Object y con ello el mtodo finalize(). Antes de que la JVM decida eliminar un objeto perdido, ejecuta este mtodo. Gracias a ello podemos por ejemplo trabajar con una serie de elementos, eliminar la referencia a los mismos y no preocuparnos de guardar los datos esenciales en una base de datos (siempre que se reimplemente finalize() en ese objeto). Dejo un mtodo ilustrativo muy simple que muestra el funcionamiento de finalize(); 1 public class Finalizando{ 2 3 String nombre; 4 5 Finalizando (String pNombre){ 6 7 this.nombre = pNombre; 8 9 } 10 11 protected void finalize(){ 12 System.out.println(this.nombre); 13 } 14 public void pasarGarbageCollector(){ 15 16 Runtime garbage = Runtime.getRuntime();

Pablo Estuardo Medrano Velasquez 201222552


17 garbage.gc(); 18 } 19 public static void main (String[] args){ 20 21 Finalizando persona = new Finalizando(&quot;Marta&quot;); 22 persona = null; 23 this.pasarGarbageCollector(); 24 25 } 26} El resultado de esto sera imprimir por consola Marta. El ejemplo es algo banal, pero imaginemos que tenemos un ArrayList<Persona> y que queremos recorrerlo mediante un while empleando un miArray.remove(0) a fin de no tener que manejar un contador y sabiendo que no se emplearn de nuevo esos objetos una vez sus datos han sido almacenados en una base de datos. Para ello, pese a que no lo recomiende, puede implementarse el mtodo finalize() y despreocuparse uno de ello a posteriori. Una cosa a tener en cuenta si se decide hacer esto, es que que nosotros dejemos sin referencia antes a un objeto que a otro, no implica que el Garbage Collector ejecute antes el finalize() de ese objeto.

Vous aimerez peut-être aussi