Pregunta

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

¿La basura de la pila también se recoge?

¿Cómo se recupera la memoria de la pila?

No hay solución correcta

Otros consejos

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

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

A Thomas Pornin dala una respuesta más detallada, busque eso para obtener más detalles.

La pila no es basura recolectada en Java.

La pila asignada para una llamada de método dado se libera cuando el método regresa. Como esa es una estructura LIFO muy simple, no hay necesidad de recolección de basura.

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

La pila pudo ser basura recolectada. Sin embargo, en la mayoría de las implementaciones de JVM, se maneja como, bueno, una "pila", que por definición impide 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 llamadas y una ranura para guardar el puntero de instrucciones. 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 por una excepción lanzada). Sucede 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 ha vuelto inútil. Esto implica que la vida útil del contexto para B es un subrangange de la vida útil del contexto para A. Por lo tanto, los contextos de activación (para un hilo dado) se pueden asignar con una disciplina LIFO ("Último en, primero fuera"). En palabras más simples, una pila: un nuevo contexto de activación se empuja encima de la pila de contextos, y el contexto en la parte superior será el primero en eliminar.

En la práctica, los contextos de activación (también llamados marcos de pila) están concatenados, en orden de pila, en un área dedicada. Esa área se obtiene del sistema operativo cuando se inicia el hilo, y el sistema operativo lo devuelve cuando el hilo termina. La parte superior de la pila está designada por un puntero específico, a menudo contenido en un registro de CPU (esto depende de si el JVM está interpretando o compilando el código). El "puntero al contexto de la persona que llama" es virtual; El contexto de la persona que llama se encuentra necesariamente justo debajo en el orden de la pila. El GC no interviene: el área para la pila se crea y se recupera sincrónicamente, de la actividad del hilo en sí. Así es como funciona en muchos idiomas, como C, que no tienen un GC en absoluto.

Ahora nada evita que una implementación de JVM haga lo contrario, por ejemplo, asignar contextos de activación en el montón y hacer que el GC los recolecte. Esto generalmente no se hace en máquinas virtuales Java, ya que la asignación de pila es más rápida. Pero algunos otros idiomas deben hacer tales cosas, especialmente aquellos que juegan con continuaciones mientras todavía usa un GC (por ejemplo Esquema y es call-with-current-continuation función), porque tales juegos rompen la regla LIFO explicada anteriormente.

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, encima de los demás (pushed onto the stack) y se elimina automáticamente de la parte superior (popped off the stack) a medida que se ejecuta su programa. No se recolecta la basura, y no es necesario que esa memoria se recupera automáticamente una vez que los datos salen de la pila. Y cuando digo que recuperé, no quiero decir que se desactiva, es solo que la ubicación en la memoria de la pila donde se almacenan los próximos datos se reducen, a medida que se apagan los datos.

Por supuesto, eso no quiere decir que no necesite preocuparse por la pila. Si ejecuta una función recursiva muchas veces, eventualmente usará 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 reclama a medida que las funciones entran y dejan el 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 lanzó al sistema operativo.

Si se refiere a la memoria utilizada en la pila, no se recolecta basura.
La máquina virtual Java utiliza instrucciones explícitas de bytecode para reservar y liberar memoria en la pila, el compilador generan estas instrucciones y administra la vida útil de primitivas como int, boolean, doble y referencias de objetos 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 ningún JVM que ya lo respalde.
Por lo tanto, no, no hay recolección de basura para la pila en sí, solo el compilador generó instrucciones de empuje 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 el hilo termina y el objeto de hilo ya no se hace referencia.

Todos los objetos en Java se asignan en el montón. (Al menos en lo que respecta a la especificación, la implementación real puede asignarlos en la pila si se comportan de manera 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 solo marco de pila, y se puede demostrar que la referencia no se usará nuevamente, entonces se puede recopilar el objeto. Si el objeto solo se usa para leer un campo, entonces esa lectura del campo puede optimizarse hacia adelante y el objeto recopilado antes de lo que cabría esperar.

Esto no suele importar a menos que esté usando finalistas (o presumiblemente References). En ese caso, debe tener cuidado y usar cerraduras/volátiles para hacer cumplir un happens-before relación.

Cuando los hilos se detengan, típicamente se desacalzará toda la pila.

Todo lo ubicado 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".

Nadie, los datos se empujan y aparecen de la pila, ya que tiene variables internas en métodos, durante las llamadas de métodos, etc. No necesita preocuparse 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. Referencias a los objetos, creados en Heap, y están siendo referidos por el método

Estos valores se empujan como marcos de pila a la pila para cada llamada de método. Dado que la pila sigue el pedido de 'First-Out' ', al final de cada llamada de método, cada marco de pila que contiene todos los datos específicos del método y las referencias a los objetos, si corresponde, se extrae.

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

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top