usar ejemplo codigo java garbage-collection gc-roots

java - ejemplo - private jlabel



¿La basura acumulada se recoge en Java? (9)

La memoria del montón es basura recolectada en Java.

¿También se recoge la basura de la pila?

¿Cómo se recupera la memoria de pila?


La memoria en la pila contiene parámetros de método y variables locales (para ser precisos: las referencias de objetos y variables en sí para tipos primitivos). Eso se eliminará automáticamente si abandona el método. Si las variables son referencias (a objetos), los objetos en sí están en el montón y manejados por el recolector de basura.

Por lo tanto, la pila no se recolecta de la misma manera que el montón, pero la pila es una forma de gestión automática de memoria propia (que es anterior a la recolección de basura).

Thomas Pornin da una respuesta más detallada , investigue eso para más detalles.


La parte de la pila de la memoria funciona como una "pila". Sé que suena mal, pero así es exactamente como funciona. Los datos se agregan a la parte superior, uno encima del otro (se pushed onto the stack ) y se eliminan automáticamente de la parte superior (que popped off the stack ) a medida que se ejecuta el programa. No es basura recolectada, y no es necesario, ya que esa memoria se recupera automáticamente una vez que los datos se extraen de la pila. Y cuando digo reclamado, no me refiero a que se desasigne, es solo que la ubicación en la memoria de la pila donde se almacenarán los próximos datos disminuye, a medida que los datos se quitan.

Por supuesto, eso no significa que no necesites preocuparte por la pila. Si ejecuta una función recursiva muchas veces, eventualmente agotará todo el espacio de la pila. Lo mismo si llama a muchas funciones, especialmente si tienen muchos parámetros y / o variables locales.

Pero la conclusión es que la memoria de la pila se usa y se recupera cuando las funciones entran y salen del alcance automáticamente. Entonces, al final de la ejecución de su programa, toda la memoria de la pila sería gratuita y luego se devolvería al sistema operativo.


La pila podría ser basura recolectada. Sin embargo, en la mayoría de las implementaciones de JVM, se maneja como, bueno, una "pila", que por definición excluye la recolección de basura.

Lo que llamamos la pila es la acumulación de contextos de activación de métodos : para cada método invocado, esta es la estructura conceptual que contiene los argumentos del método, las variables locales, un puntero oculto al contexto para el método de llamada y un espacio para guardar la instrucción puntero. El contexto de activación no es accesible como tal desde el lenguaje Java en sí. Un contexto se vuelve inútil cuando el método sale (con un return o debido a una excepción lanzada). Ocurre que cuando un método A llama a un método B, se garantiza que cuando A recupera el control, el contexto para B se vuelve inútil. Esto implica que la duración del contexto para B es un subrango del tiempo de vida del contexto para A. Por lo tanto, los contextos de activación (para un hilo dado) pueden asignarse con una disciplina LIFO ("último en entrar, primero en salir"). En palabras más simples, una pila: un nuevo contexto de activación se coloca en la parte superior de la pila de contextos, y el contexto en la parte superior será el primero en eliminarse.

En la práctica, los contextos de activación (también llamados cuadros de pila ) se concatenan, en orden de pila, en un área dedicada. Esa área se obtiene del sistema operativo cuando se inicia el subproceso y el sistema operativo la recupera cuando finaliza el subproceso. La parte superior de la pila está designada por un puntero específico, a menudo incluido en un registro de la CPU (esto depende de si la JVM está interpretando o compilando el código). El "puntero al contexto de la persona que llama" es virtual; el contexto del que llama se encuentra necesariamente justo debajo en orden de pila. El GC no interviene: el área de la pila se crea y recupera de forma síncrona, a partir de la actividad de la hebra en sí misma. Esta es también la forma en que funciona en muchos idiomas, como C , que no tienen un GC en absoluto.

Ahora, nada impide que una implementación de JVM haga lo contrario, por ejemplo, asignando contextos de activación en el montón y haciéndolos recolectar por el GC. Esto no suele hacerse en Java Virtual Machines ya que la asignación de la pila es más rápida. Pero algunos otros lenguajes necesitan hacer tales cosas, más notablemente aquellos que juegan con continuations mientras todavía usan un GC (por ejemplo, Scheme y su función call-with-current-continuation ), porque tales juegos rompen la regla LIFO explicada anteriormente.


La pila no es basura recolectada en Java.

La pila asignada para una llamada de método dada se libera cuando el método retorna. Dado que se trata de una estructura LIFO muy simple, no hay necesidad de recolección de basura.

Un lugar donde la pila y la recolección de basura interactúan es que las referencias en la pila son raíces de GC (lo que significa que son las referencias de raíz desde las cuales se decide la accesibilidad).


Nadie, los datos se insertan y extraen de la pila ya que tiene variables internas en los métodos, durante las llamadas a métodos, etc. No es necesario que se preocupe por esto.


No. La pila no es basura recolectada en Java. Cada hilo tiene su propia pila y contiene:

  1. Valores específicos del método (que son de corta duración) y
  2. Las referencias a los objetos, creadas en el montón, y están siendo referidas por el método

Estos valores se envían como marcos de pila a la pila para cada llamada de método. Dado que la pila sigue el orden ''Last-in-First-out'', al final de cada llamada a un método, cada cuadro de pila que contiene todos los datos específicos del método y las referencias a los objetos, si los hay, se abren.

Por lo tanto, los datos en la pila se limpian automáticamente una vez que el método / programa queda fuera del alcance.


Si se refiere a la memoria utilizada en la pila, no es basura.
La máquina virtual Java usa instrucciones explícitas de bytecode para reservar y liberar memoria en la pila, estas instrucciones son generadas por el compilador y administran la vida útil de primitivas como int, boolean, double y referencias de objeto en la pila.
Ha habido planes para implementar una llamada optimización de llamadas de cola, que eliminaría algunas entradas de la pila una vez que se sabe que ya no se usan, pero no conozco ninguna JVM que ya sea compatible con esto.
Así que no, no hay recolección de basura para la pila en sí misma, solo el compilador generó instrucciones push y pop para administrar el uso de la memoria.

La pila en sí es parte de un hilo. La pila se asigna cuando se crea el objeto de subproceso y se recoge la basura después de que finaliza el subproceso y ya no se hace referencia al objeto de subproceso.


Todo lo que se encuentra en la pila es tratado como raíces globales por un recolector de basura. Entonces, sí, definitivamente puedes decir que la pila es "basura recolectada".


Todos los objetos en Java se asignan en el montón. (Al menos en cuanto a la especificación, la implementación real puede asignarlos en la pila si se comportan de forma transparente como si estuvieran en el montón).

Exactamente lo que es coleccionable es un poco sutil. Si la única referencia a un objeto está en un único marco de pila, y se puede mostrar que la referencia no se usará nuevamente, entonces el objeto puede ser recolectado. Si el objeto solo se usa para leer un campo, entonces esa lectura de campo puede optimizarse hacia adelante y el objeto recolectado antes de lo que cabría esperar.

Esto no suele importar a menos que esté utilizando finalizadores (o presumiblemente Reference s). En ese caso, debe tener cuidado y usar bloqueos / volátiles para imponer una relación de happens-before .

Cuando los hilos se detienen, normalmente la pila entera será desasignada.