¿Dónde se almacenan los métodos estáticos y las variables estáticas en Java?

115

Por ejemplo:

class A {
    static int i=0;
    static int j;

   static void method() {
       // static k=0; can't use static for local variables only final is permitted
       // static int L;
    }
}

¿Dónde se almacenarán estas variables en Java, en el montón o en la memoria de pila? ¿Cómo se almacenan?

Nav
fuente
2
enlace muy útil para comprender la recolección de basura en el sitio web oficial de Oracle: oracle.com/webfolder/technetwork/tutorials/obe/java/gc01/…
Arnav Joshi

Respuestas:

144

Los métodos estáticos (de hecho, todos los métodos) y las variables estáticas se almacenan en la PermGensección del montón, ya que son parte de los datos de reflexión (datos relacionados con la clase, no relacionados con la instancia).

Actualización para aclaraciones :

Tenga en cuenta que solo las variables y sus valores técnicos (primitivas o referencias) se almacenan en el espacio de PermGen.

Si su variable estática es una referencia a un objeto, ese objeto en sí se almacena en las secciones normales del montón (generación joven / vieja o espacio de supervivientes). Esos objetos (a menos que sean objetos internos como clases, etc.) no se almacenan en el espacio de PermGen.

Ejemplo:

static int i = 1; //the value 1 is stored in the PermGen section
static Object o = new SomeObject(); //the reference(pointer/memory address) is stored in the PermGen section, the object itself is not.


Una palabra sobre la recolección de basura:

No , no depender finalize()ya que no está garantizado para funcionar. Depende totalmente de la JVM decidir cuándo ejecutar el recolector de basura y qué recolectar, incluso si un objeto es elegible para la recolección de basura.

Por supuesto, puede establecer una variable estática en nula y, por lo tanto, eliminar la referencia al objeto en el montón, pero eso no significa que el recolector de basura lo recopile (incluso si no hay más referencias).

Además, finalize()se ejecuta solo una vez, por lo que debe asegurarse de que no genere excepciones o evite que se recopile el objeto. Si detiene la finalización a través de alguna excepción, finalize()no se invocará en el mismo objeto por segunda vez.

Una nota final : cómo se almacenan el código, los datos en tiempo de ejecución, etc., depende de la JVM que se utilice, es decir, HotSpot podría hacerlo de manera diferente a JRockit y esto podría incluso diferir entre versiones de la misma JVM. Lo anterior se basa en HotSpot para Java 5 y 6 (esos son básicamente los mismos) ya que al momento de responder diría que la mayoría de la gente usa esos JVM. Debido a cambios importantes en el modelo de memoria a partir de Java 8, las declaraciones anteriores pueden no ser ciertas para Java 8 HotSpot, y no verifiqué los cambios de Java 7 HotSpot, así que supongo que lo anterior sigue siendo cierto para esa versión. pero no estoy seguro aquí.

Thomas
fuente
1
Ahh, ¿estás seguro de las variables estáticas? AFAIK PermGen solo almacena las definiciones, no el valor real.
Amir Raminfar
2
@Amir Estoy bastante seguro de que la variable en sí está almacenada en el espacio permgen, cualquier objeto al que se hace referencia probablemente se asignará al montón. Esto podría agregar algo de información: stackoverflow.com/questions/3800444/…
Thomas
1
Ah, sí, la definición de la variable se almacena en permgen. Pero el valor estará en el montón. Su respuesta sugirió que el valor también se almacena en PermGen.
Amir Raminfar
1
@Matthew, ¿cómo entiendes mi respuesta? A dijo que las variables se almacenan en la sección permgen (primitivas / referencias), no en los objetos a los que hacen referencia. Depende de cómo vea el valor de una variable .
Thomas
1
@Nav no todas las partes del montón son basura recolectada de forma predeterminada y, a veces, las clases y, por lo tanto, las variables estáticas no se pueden recopilar, ya que los cargadores de clases todavía tienen una referencia sobre ellas. Además, no debe confiar en que el recolector de basura se ejecute, ya que eso depende totalmente de la JVM (decide cuándo ejecutar y qué recopilar, solo puede proporcionar sugerencias como "Me gustaría que ejecute gc ahora" :)) .
Thomas
25

Las variables de clase (variables estáticas) se almacenan como parte de las Class objectasociadas con esa clase. Este objeto de clase solo puede ser creado por JVM y se almacena en permanent generation.

También algunos han respondido que se almacena en un área que no es del montón, que se llama Method Area.Incluso esta respuesta no es incorrecta. Es solo un tema debatible si Permgen Area es parte del montón o no. Evidentemente, las percepciones difieren de una persona a otra. En mi opinión, proporcionamos espacio de pila y espacio de permgen de manera diferente en los argumentos de JVM. Por tanto, es una buena suposición tratarlos de forma diferente.

Otra forma de verlo

Los gestores de memoria JVM crean agrupaciones de memoria durante el tiempo de ejecución. El grupo de memoria puede pertenecer a la memoria de pila o no. Un grupo de constante de tiempo de ejecución es una representación de tiempo de ejecución por clase o por interfaz de la tabla constant_pool en un archivo de clase. Cada grupo de constantes de tiempo de ejecución se asigna desde el área de métodos de la máquina virtual Java y las variables estáticas se almacenan en esta área de métodos. Además, esta no-pila no es más que un área de generación permanente.En realidad, el área de método es parte de la generación permanente ( Referencia ).

ingrese la descripción de la imagen aquí

Aniket Thakur
fuente
¿El área de método no es un subconjunto de la sección PermGen de la memoria? ¿Por qué ha mostrado el área de método como parte de la memoria que no es de montón cuando, creo, ellos (PermGen junto con el área de método (clase)) son parte del área de montón más grande de la JVM?
Kaveesh Kanwal
Lea la última línea -Also this non-heap is nothing but perm gen area.Actually Method area is part of perm gen.
Aniket Thakur
1
@AniketThakur ha mostrado el área de método como parte de la memoria que no es del montón, pero de acuerdo con los documentos de Oracle , aquí, docs.oracle.com/javase/specs/jvms/se7/html/… , se menciona que el área de método es lógicamente parte de el montón.
Karan
21

Antes de Java 8:

Las variables estáticas se almacenaron en el espacio permgen (también llamado área de método).

PermGen Space también se conoce como área de método

PermGen Space utilizado para almacenar 3 cosas

  1. Datos de nivel de clase (metadatos)
  2. cuerdas internadas
  3. variables estáticas

Desde Java 8 en adelante

Las variables estáticas se almacenan en el propio Heap. A partir de Java 8, se eliminó el PermGen Space y se introdujo un nuevo espacio denominado MetaSpace, que ya no es parte de Heap a diferencia del Permgen Space anterior. Meta-Space está presente en la memoria nativa (memoria proporcionada por el sistema operativo a una aplicación en particular para su propio uso) y ahora solo almacena los metadatos de la clase.

Las cadenas internas y las variables estáticas se mueven al montón.

Para obtener información oficial, consulte: JEP 122: Eliminar el espacio de generación permanente

Manish Kumar
fuente
cuando dice "montón" para variables estáticas> Java8, ¿dónde exactamente: OldGen?
Ewoks
15

Esta es una pregunta con una respuesta simple y una respuesta larga.

La respuesta simple es el montón. Las clases y todos los datos que se aplican a las clases (no los datos de instancia) se almacenan en la sección de generación permanente del montón.

La respuesta larga ya está en desbordamiento de pila:

Hay una descripción completa de la recolección de basura y memoria en la JVM , así como una respuesta que habla de manera más concisa al respecto.

Vasiliy Sharapov
fuente
3
¡Cosa segura! No olvides votar a favor de esos tipos si los encuentras útiles.
Vasiliy Sharapov
11

Se almacena en el montón al que hace referencia la definición de clase. Si lo piensas, no tiene nada que ver con la pila porque no hay alcance.

Amir Raminfar
fuente
5

Además de la respuesta de Thomas, las variables estáticas se almacenan en un área que no es del montón, que se llama Área de método.

Vipin
fuente
4

Como las variables estáticas son variables de nivel de clase, almacenarán " generación permanente " de memoria de pila. Mire esto para obtener más detalles de JVM. Esperando que esto sea útil

Ramesh Papaganti
fuente
3

las variables estáticas se almacenan en el montón

CLS
fuente
7
Las variables estáticas se almacenan en el espacio PremGen en la memoria, sus valores se almacenan en Heap.
Akash5288