Onde os métodos estáticos e variáveis ​​estáticas são armazenados em Java?

115

Por exemplo:

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;
    }
}

Onde essas variáveis ​​serão armazenadas em Java, no heap ou na memória da pilha? Como eles são armazenados?

Nav
fonte
2
link muito útil para entender a coleta de lixo no site oficial da Oracle: oracle.com/webfolder/technetwork/tutorials/obe/java/gc01/…
Arnav Joshi

Respostas:

144

Os métodos estáticos (na verdade, todos os métodos), bem como as variáveis ​​estáticas, são armazenados na PermGenseção do heap, pois fazem parte dos dados de reflexão (dados relacionados à classe, não relacionados à instância).

Atualização para esclarecimento :

Observe que apenas as variáveis ​​e seus valores técnicos (primitivas ou referências) são armazenados no espaço PermGen.

Se sua variável estática for uma referência a um objeto, esse objeto em si é armazenado nas seções normais do heap (geração jovem / velha ou espaço sobrevivente). Esses objetos (a menos que sejam objetos internos, como classes, etc.) não são armazenados no espaço PermGen.

Exemplo:

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.


Uma palavra sobre coleta de lixo:

Você não contar comfinalize() como não é garantido para ser executado. É totalmente responsabilidade da JVM decidir quando executar o coletor de lixo e o que coletar, mesmo se um objeto for elegível para a coleta de lixo.

É claro que você pode definir uma variável estática como nula e, portanto, remover a referência ao objeto no heap, mas isso não significa que o coletor de lixo irá coletá-lo (mesmo se não houver mais referências).

Além disso, finalize()é executado apenas uma vez, portanto, certifique-se de não lançar exceções ou impedir de outra forma que o objeto seja coletado. Se você interromper a finalização por meio de alguma exceção, finalize()não será chamado no mesmo objeto uma segunda vez.

Uma nota final : como o código, os dados de tempo de execução etc. são armazenados depende da JVM que é usada, ou seja, o HotSpot pode fazer isso de forma diferente do JRockit e isso pode até diferir entre as versões da mesma JVM. O texto acima é baseado no HotSpot para Java 5 e 6 (esses são basicamente os mesmos), já que na hora de responder eu diria que a maioria das pessoas usa esses JVMs. Devido a grandes mudanças no modelo de memória a partir do Java 8, as declarações acima podem não ser verdadeiras para o Java 8 HotSpot - e eu não verifiquei as mudanças do Java 7 HotSpot, então acho que o acima ainda é verdadeiro para essa versão, mas não tenho certeza aqui.

Thomas
fonte
1
Ahh você tem certeza sobre variáveis ​​estáticas? AFAIK PermGen armazena apenas as definições, não o valor real.
Amir Raminfar
2
@Amir Tenho quase certeza de que a própria variável é armazenada no espaço permgen, qualquer objeto referenciado provavelmente será alocado no heap. Isso pode adicionar algumas informações: stackoverflow.com/questions/3800444/…
Thomas
1
Ah sim, a definição da variável é armazenada em permgen. Mas o valor estará na pilha. Sua resposta sugeriu que o valor também está armazenado em PermGen.
Amir Raminfar
1
@Matthew como você entende minha resposta? Disse que as variáveis são armazenadas na seção permgen (primitivas / referências) e não nos objetos aos quais se referem. Depende de como você vê o valor de uma variável .
Thomas
1
@Nav nem todas as partes do heap são coletadas como lixo por padrão e, às vezes, as classes e, portanto, as variáveis ​​estáticas não podem ser coletadas, pois os carregadores de classes ainda têm uma referência sobre elas. Além disso, você não deve depender do coletor de lixo para ser executado, pois isso depende totalmente da JVM (ele decide quando executar e o que coletar, você só pode fornecer dicas como "Gostaria que executasse gc agora" :)) .
Thomas
25

Variáveis ​​de classe (variáveis ​​estáticas) são armazenadas como parte do Class objectassociado a essa classe. Este objeto de classe só pode ser criado por JVM e é armazenado empermanent generation .

Além disso, alguns responderam que ele é armazenado em uma área não heap, que é chamada Method Area. Mesmo esta resposta não está errada. É apenas um tópico discutível se a área de Permgen faz parte do heap ou não. Obviamente, as percepções variam de pessoa para pessoa. Em minha opinião, fornecemos o espaço de heap e o espaço de permgen de maneira diferente nos argumentos da JVM. Portanto, é uma boa suposição tratá-los de maneira diferente.

Outra maneira de ver isso

Os pools de memória são criados por gerenciadores de memória JVM durante o tempo de execução. O pool de memória pode pertencer à memória heap ou não heap. Um pool de constante de tempo de execução é uma representação de tempo de execução por classe ou por interface da tabela constant_pool em um arquivo de classe. Cada conjunto de constantes de tempo de execução é alocado da área de método da máquina virtual Java e as Variáveis ​​estáticas são armazenadas nesta Área de Método. Além disso, este não-heap nada mais é do que uma área de perm gen. Na verdade, a área de método faz parte da perm gen. ( Referência )

insira a descrição da imagem aqui

Aniket Thakur
fonte
A área do método não é um subconjunto da seção PermGen da memória? Por que você mostrou a área de método como parte da memória não heap quando, eu acho, eles (PermGen junto com a área de método (classe)) fazem parte da área de heap maior da JVM?
Kaveesh Kanwal
Leia a última linha -Also this non-heap is nothing but perm gen area.Actually Method area is part of perm gen.
Aniket Thakur
1
@AniketThakur você mostrou a área de método como parte da memória não heap, mas de acordo com a documentação do oracle, aqui, docs.oracle.com/javase/specs/jvms/se7/html/… , é mencionado que a área de método logicamente faz parte de a pilha.
Karan
21

Antes do Java 8:

As variáveis ​​estáticas foram armazenadas no espaço permgen (também chamado de área de método).

O Espaço PermGen também é conhecido como Área de Método

Espaço PermGen usado para armazenar 3 coisas

  1. Dados de nível de classe (metadados)
  2. cordas internadas
  3. variáveis ​​estáticas

De Java 8 em diante

As variáveis ​​estáticas são armazenadas no próprio Heap. A partir do Java 8 em diante, o Espaço PermGen foi removido e um novo espaço denominado MetaSpace é introduzido, o qual não é mais parte do Heap ao contrário do Espaço Permgen anterior. Meta-Space está presente na memória nativa (memória fornecida pelo sistema operacional para um determinado aplicativo para seu próprio uso) e agora armazena apenas os metadados da classe.

As strings internas e variáveis ​​estáticas são movidas para o próprio heap.

Para obter informações oficiais, consulte: JEP 122: Remova o Espaço Gerador Permanente

Manish Kumar
fonte
quando você diz "heap-se" para variáveis ​​estáticas> Java8, onde exatamente: OldGen?
Ewoks
15

Esta é uma pergunta com uma resposta simples e uma resposta prolixa.

A resposta simples é a pilha. Classes e todos os dados que se aplicam a classes (não dados de instância) são armazenados na seção Geração Permanente do heap.

A longa resposta já está em excesso:

Há uma descrição completa da memória e coleta de lixo na JVM , bem como uma resposta que fala de forma mais concisa sobre isso.

Vasiliy Sharapov
fonte
3
Coisa certa! Não se esqueça de votar a favor desses caras se você achar que eles são úteis.
Vasiliy Sharapov
11

Ele é armazenado no heap referenciado pela definição de classe. Se você pensar sobre isso, não tem nada a ver com pilha porque não há escopo.

Amir Raminfar
fonte
5

Além da resposta de Thomas, as variáveis ​​estáticas são armazenadas em uma área não heap que é chamada de Área de Método.

Vipin
fonte
4

Como as variáveis ​​estáticas são variáveis ​​de nível de classe, elas armazenarão a " geração permanente " de memória heap. Verifique isso para obter mais detalhes sobre JVM. Esperando que isso seja útil

Ramesh Papaganti
fonte
3

variáveis ​​estáticas são armazenadas no heap

CLS
fonte
7
Variáveis ​​estáticas são armazenadas no espaço PremGen na memória, seus valores são armazenados no Heap.
Akash5288 de