Soy nuevo en Java y estoy confundido acerca del recolector de basura en Java. ¿Qué hace realmente y cuándo entra en acción? Describa algunas de las propiedades del recolector de basura en Java.
Soy nuevo en Java y estoy confundido acerca del recolector de basura en Java. ¿Qué hace realmente y cuándo entra en acción? Describa algunas de las propiedades del recolector de basura en Java.
Respuestas:
El recolector de basura es un programa que se ejecuta en la máquina virtual Java y que elimina los objetos que ya no están siendo utilizados por una aplicación Java. Es una forma de gestión automática de la memoria .
Cuando se ejecuta una aplicación Java típica, está creando nuevos objetos, como String
s y File
s, pero después de cierto tiempo, esos objetos ya no se utilizan. Por ejemplo, eche un vistazo al siguiente código:
for (File f : files) {
String s = f.getName();
}
En el código anterior, String s
se crea en cada iteración del for
bucle. Esto significa que en cada iteración, se asigna un poco de memoria para crear un String
objeto.
Volviendo al código, podemos ver que una vez que se ejecuta una sola iteración, en la siguiente iteración, el String
objeto que se creó en la iteración anterior ya no se usa más; ese objeto ahora se considera "basura".
Eventualmente, comenzaremos a recibir mucha basura y la memoria se usará para objetos que ya no se usan. Si esto continúa, eventualmente la máquina virtual Java se quedará sin espacio para crear nuevos objetos.
Ahí es donde interviene el recolector de basura.
El recolector de basura buscará objetos que ya no se estén usando y se deshará de ellos, liberando la memoria para que otros objetos nuevos puedan usar esa parte de la memoria.
En Java, la gestión de la memoria está a cargo del recolector de basura, pero en otros lenguajes como C, es necesario realizar la gestión de la memoria por su cuenta utilizando funciones como malloc
yfree
. La gestión de la memoria es una de esas cosas en las que es fácil cometer errores, lo que puede conducir a lo que se denomina pérdidas de memoria , lugares donde la memoria no se recupera cuando ya no se utiliza.
Los esquemas automáticos de administración de memoria, como la recolección de basura, hacen que el programador no tenga que preocuparse tanto por los problemas de administración de la memoria, para que pueda concentrarse más en desarrollar las aplicaciones que necesita desarrollar.
Libera la memoria asignada a los objetos que el programa ya no utiliza, de ahí el nombre "basura". Por ejemplo:
public static Object otherMethod(Object obj) {
return new Object();
}
public static void main(String[] args) {
Object myObj = new Object();
myObj = otherMethod(myObj);
// ... more code ...
}
Sé que esto es extremadamente artificial, pero aquí, después de llamar, otherMethod()
el original Object
creado se vuelve inalcanzable, y eso es "basura" que se recolecta.
En Java, el GC se ejecuta automáticamente, pero también puede llamarlo explícitamente System.gc()
e intentar forzar una recolección de basura importante. Como señala Pascal Thivent, realmente no debería tener que hacer esto y podría hacer más daño que bien (consulte esta pregunta ).
Para obtener más información, consulte la entrada de wikipedia sobre recolección de basura y ajuste de recolección de basura (de Oracle)
System.gc()
no obliga a GC a ejecutarse.
myObj
antes de que otherMethod
se realice la llamada a , porque myObj
ya no es accesible en ese punto.
System.gc()
, el objetivo de tener un GC es no tener que hacer eso.
Un objeto se vuelve elegible para la recolección de basura o GC si no se puede acceder a él desde ningún hilo en vivo o por referencias estáticas.
En otras palabras, puede decir que un objeto se vuelve elegible para la recolección de basura si todas sus referencias son nulas. Las dependencias cíclicas no se cuentan como referencia, por lo que si el objeto A tiene una referencia al objeto B y el objeto B tiene una referencia al objeto A y no tienen ninguna otra referencia en vivo, entonces tanto los objetos A como B serán elegibles para la recolección de basura.
Generaciones de montón para recolección de basura -
Los objetos Java se crean Heap
y Heap
se dividen en tres partes o generaciones para la recolección de basura en Java, estos se denominan Generación joven (nueva), Generación permanente (antigua) y Área permanente del montón.
New Generation se divide en tres partes conocidas como espacio Eden, espacio Survivor 1 y Survivor 2. Cuando un objeto se crea por primera vez en un montón, se crea en una nueva generación dentro del espacio Edén y, después de la recolección de basura menor posterior, si un objeto sobrevive, se mueve al sobreviviente 1 y luego al sobreviviente 2 antes de que la recolección de basura principal mueva ese objeto a la generación anterior o titular .
El espacio permanente de Java Heap es donde JVM almacena metadatos sobre clases y métodos, grupo de cadenas y detalles de nivel de clase.
Consulte aquí para obtener más información: Recolección de basura
No puede obligar a JVM a ejecutar Garbage Collection, aunque puede realizar una solicitud utilizando el método System.gc()
o Runtime.gc()
.
public static void gc() {
Runtime.getRuntime().gc();
}
public native void gc(); // note native method
Algoritmo de marcado y barrido -
Este es uno de los algoritmos más populares utilizados por la recolección de basura. Cualquier algoritmo de recolección de basura debe realizar 2 operaciones básicas. Uno, debería poder detectar todos los objetos inalcanzables y, en segundo lugar, debe recuperar el espacio de pila utilizado por los objetos basura y hacer que el espacio esté disponible nuevamente para el programa.
Las operaciones anteriores son realizadas por Mark and Sweep Algorithm en dos fases:
lea aquí para más detalles - Algoritmo de marcado y barrido
Garbage Collector es parte de JRE que se asegura de que el objeto al que no se hace referencia se libere de la memoria.
Por lo general, se ejecuta cuando la aplicación se queda sin memoria. AFAIK tiene un gráfico que representa los vínculos entre los objetos y los objetos aislados se pueden liberar.
Para ahorrar rendimiento, los objetos actuales agrupados en generaciones, cada vez que GC escanea un objeto y descubre que todavía se hace referencia, su recuento de generación se incrementa en 1 (a un valor máximo máximo, 3 o 4, creo), y la nueva generación se escanea primero (cuanto más corto sea el objeto en la memoria, más probablemente ya no sea necesario), por lo que no todos los objetos se escanean cada vez que se ejecuta el GC.
lea esto para obtener más información.
El recolector de basura permite que su computadora simule una computadora con memoria infinita. El resto es solo un mecanismo.
Para ello, detecta cuándo ya no se puede acceder a fragmentos de memoria desde su código y devuelve esos fragmentos a la tienda gratuita.
EDITAR: Sí, el enlace es para C #, pero C # y Java son idénticos en este sentido.
Mucha gente piensa que la recolección de basura recolecta y desecha objetos muertos.
En realidad, ¡la recolección de basura de Java está haciendo lo contrario! Los objetos vivos se rastrean y todo lo demás se designa como basura.
Cuando un objeto ya no se usa, el recolector de basura recupera la memoria subyacente y la reutiliza para la futura asignación de objetos. Esto significa que no hay una eliminación explícita y no se devuelve memoria al sistema operativo. Para determinar qué objetos ya no están en uso, la JVM ejecuta de forma intermitente lo que se llama muy acertadamente un algoritmo de marca y barrido.
Consulte esto para obtener más información detallada: http://javabook.compuware.com/content/memory/how-garbage-collection-works.aspx
Para decirlo en los términos más simples que incluso un no programador puede entender, cuando un programa procesa datos, crea datos intermedios y espacio de almacenamiento (variables, matrices, ciertos metadatos de objetos, etc.) para esos datos.
Cuando se accede a estos objetos a través de funciones o sobre un cierto tamaño, se asignan desde un montón central. Luego, cuando ya no se necesiten, es necesario limpiarlos.
Hay algunos artículos muy buenos en línea sobre cómo funciona esto, así que solo cubriré la definición muy básica.
El GC es básicamente la función que realiza esta limpieza. Para hacer esto, borra las entradas de la tabla a las que no hace referencia ningún objeto activo, eliminando efectivamente los objetos, luego copia y compacta la memoria. Es un poco más complicado que esto, pero entiendes la idea.
El gran problema es que algunas partes de este proceso a menudo requieren que toda la máquina virtual de Java deba detenerse temporalmente para que se lleve a cabo, además de que todo este proceso consume mucho ancho de banda de memoria y procesador. Las diversas opciones de GC y las opciones de ajuste para cada uno están diseñadas para equilibrar estos diversos problemas con todo el proceso de GC.
La recolección de basura en Java (y también en otros lenguajes / plataformas) es una forma para que el entorno de tiempo de ejecución de Java (JRE) reutilice la memoria de los objetos de Java que ya no son necesarios. De manera simplista, cuando el JRE se inicia inicialmente, solicita al sistema operativo (O / S) una cierta cantidad de memoria. A medida que el JRE ejecuta su (s) aplicación (es), usa esa memoria. Cuando su aplicación termina de usar esa memoria, el "recolector de basura" de JRE aparece y reclama esa memoria para que la utilicen diferentes partes de sus aplicaciones existentes. El "recolector de basura" de JRE es una tarea en segundo plano que siempre se está ejecutando y trata de seleccionar las horas en las que el sistema está inactivo para continuar con sus ejecuciones de basura.
Una analogía del mundo real sería el de los basureros que vienen a tu casa y recogen tu basura reciclable ... eventualmente, es reutilizada de otras formas por ti y / o otras personas.
El recolector de basura se puede ver como un administrador de recuento de referencias. si se crea un objeto y su referencia se almacena en una variable, su recuento de referencias aumenta en uno. durante el curso de la ejecución si esa variable está asignada con NULL. el recuento de referencias para ese objeto disminuye. por lo que el recuento de referencia actual para el objeto es 0. Ahora, cuando se ejecuta el recolector de basura, comprueba los objetos con el recuento de referencia 0. y libera los recursos asignados a él.
La invocación del recolector de basura está controlada por políticas de recolección de basura.
Puede obtener algunos datos aquí. http://www.oracle.com/technetwork/java/gc-tuning-5-138395.html
El recolector de basura es un componente de jvm.
Se utiliza para recolectar basura cuando la CPU se libera.
Aquí basura significa objetos no utilizados que se ejecuta en segundo plano del programa principal
para monitorear el estado del programa principal.
La recolección automática de basura es el proceso de mirar la memoria del montón, identificar qué objetos están en uso y cuáles no, y eliminar los objetos no usados. Un objeto en uso, o un objeto referenciado, significa que alguna parte de su programa aún mantiene un puntero a ese objeto. Un objeto no utilizado, o un objeto no referenciado, ya no es referenciado por ninguna parte de su programa. Por lo tanto, la memoria utilizada por un objeto no referenciado se puede recuperar.
En un lenguaje de programación como C, asignar y desasignar memoria es un proceso manual. En Java, el recolector de basura maneja automáticamente el proceso de desasignación de memoria. Consulte el enlace para una mejor comprensión. http://www.oracle.com/webfolder/technetwork/tutorials/obe/java/gc01/index.html
La recolección de basura se refiere al proceso de liberar automáticamente memoria en el montón eliminando objetos que ya no son accesibles en su programa. El montón es una memoria a la que se hace referencia como almacenamiento gratuito, representa una gran cantidad de memoria no utilizada asignada a su aplicación Java.
Los principios básicos de la recolección de basura son encontrar objetos de datos en un programa al que no se puede acceder en el futuro y recuperar los recursos utilizados por esos objetos. https://en.wikipedia.org/wiki/Garbage_collection_%28computer_science%29
Ventajas
1) Se salva de errores, que se producen cuando se libera una parte de la memoria mientras todavía hay punteros hacia ella, y se desreferencia a uno de esos punteros. https://en.wikipedia.org/wiki/Dangling_pointer
2) Errores libres dobles, que ocurren cuando el programa intenta liberar una región de memoria que ya ha sido liberada, y quizás ya haya sido asignada nuevamente.
3) Previene ciertos tipos de pérdidas de memoria, en las que un programa no logra liberar memoria ocupada por objetos que se han vuelto inalcanzables, lo que puede llevar al agotamiento de la memoria.
Desventajas
1) Consumo de recursos adicionales, impactos en el desempeño, posibles estancamientos en la ejecución del programa e incompatibilidad con la gestión manual de recursos. La recolección de basura consume recursos informáticos para decidir qué memoria liberar, aunque el programador ya conozca esta información.
2) El momento en que la basura se recolecta realmente puede ser impredecible, lo que resulta en paradas (pausas para cambiar / liberar memoria) dispersas a lo largo de una sesión. Los atascos impredecibles pueden ser inaceptables en entornos de tiempo real, en el procesamiento de transacciones o en programas interactivos.
Tutorial de Oracle http://www.oracle.com/webfolder/technetwork/tutorials/obe/java/gc01/index.html
La recolección de basura es el proceso que identifica qué objetos están en uso y cuáles no, y elimina los objetos no utilizados.
En lenguajes de programación como C, C ++, asignar y liberar memoria es un proceso manual.
int * array = new int[size];
processArray(array); //do some work.
delete array; //Free memory
El primer paso del proceso se llama marcado. Aquí es donde el recolector de basura identifica qué piezas de memoria están en uso y cuáles no.
Paso 2a. La eliminación normal elimina los objetos no referenciados dejando los objetos referenciados y los punteros al espacio libre.
Para mejorar el rendimiento, queremos eliminar los objetos no referenciados y también compactar el resto de los objetos referenciados. Queremos mantener juntos los objetos referenciados, por lo que será más rápido asignar nueva memoria.
Como se indicó anteriormente, tener que marcar y compactar todos los objetos en una JVM es ineficiente. A medida que se asignan más y más objetos, la lista de objetos crece y crece, lo que lleva a un tiempo de recolección de basura cada vez más largo.
Continúe leyendo este tutorial y sabrá cómo GC acepta este desafío.
En resumen, hay tres regiones del montón, YoungGeneration para objetos de corta duración, OldGeneration para objetos de período largo y PermanentGeneration para objetos que viven durante la vida de la aplicación, por ejemplo, clases, bibliotecas.
Como los objetos son asignados dinámicamente por el nuevo operador, puede preguntar cómo se destruyen estos objetos y cómo se libera la memoria ocupada. En otros lenguajes como C ++, es necesario liberar los objetos asignados manualmente de forma dinámica mediante el operador de eliminación. Java tiene un enfoque diferente; maneja automáticamente la desasignación. La técnica se conoce como recolección de basura .
Funciona así: cuando no hay referencias a un objeto, se asume que este objeto ya no es necesario y se puede recuperar la memoria ocupada por el objeto. No es necesario destruir objetos explícitamente como en C ++. La recolección de basura ocurre esporádicamente durante la ejecución del programa; No sucede simplemente porque hay uno o más objetos que ya no se utilizan. Además, varias implementaciones de tiempo de ejecución de Java tienen diferentes enfoques para la recolección de basura, pero la mayoría de los programadores no tienen que preocuparse por esto cuando escriben programas.
La recolección automática de basura es un proceso en el que la JVM se deshace o mantiene ciertos puntos de datos en la memoria para finalmente liberar espacio para el programa en ejecución. La memoria se envía primero a la memoria del montón, que es donde el recolector de basura (GC) hace su trabajo, luego se decide terminar o guardar. Java asume que no siempre se puede confiar en el programador, por lo que termina los elementos que cree que no necesita.