Como o pool de memória java é dividido?

224

Atualmente, estou monitorando um aplicativo Java com o jconsole. A guia de memória permite escolher entre:

Heap Memory Usage
Non-Heap Memory Usage
Memory Pool “Eden Space”
Memory Pool “Survivor Space”
Memory Pool “Tenured Gen”
Memory Pool “Code Cache”
Memory Pool “Perm Gen”

Qual a diferença entre eles ?

Dani Cricco
fonte
Supondo que você está usando o Sun JDK, a melhor resposta será encontrada em sua documentação: Sintonia de lixo Coleção (JDK 1.5) e lixo Coleção FAQ (JDK 1.4)
kdgregory

Respostas:

327

Memória de pilha

A memória heap é a área de dados de tempo de execução a partir da qual a Java VM aloca memória para todas as instâncias e matrizes de classe. O heap pode ser de tamanho fixo ou variável. O coletor de lixo é um sistema automático de gerenciamento de memória que recupera memória heap para objetos.

  • Eden Space : o pool do qual a memória é inicialmente alocada para a maioria dos objetos.

  • Espaço do Sobrevivente : O pool que contém objetos que sobreviveram à coleta de lixo do espaço do Éden.

  • Geração Tenured ou Geração Antiga : O pool contendo objetos que existem há algum tempo no espaço sobrevivente.

Memória não heap

A memória não heap inclui uma área de método compartilhada entre todos os encadeamentos e a memória necessária para o processamento interno ou otimização para a Java VM. Ele armazena estruturas por classe, como um pool constante de tempo de execução, dados de campo e método e o código para métodos e construtores. A área do método faz parte da pilha logicamente, mas, dependendo da implementação, uma Java VM não pode coletar ou compactar lixo. Como a memória heap, a área do método pode ter um tamanho fixo ou variável. A memória da área do método não precisa ser contígua.

  • Geração permanente : o pool que contém todos os dados reflexivos da própria máquina virtual, como objetos de classe e método. Com VMs Java que usam compartilhamento de dados de classe, essa geração é dividida em áreas somente leitura e leitura / gravação.

  • Cache de código : a VM Java do HotSpot também inclui um cache de código, contendo memória usada para compilação e armazenamento de código nativo.

Aqui está uma documentação sobre como usar o Jconsole .

dfa
fonte
4
Não sei se o @dfa está completamente correto, como a Especificação da Java Virtual Machine afirma claramente: "Embora a área do método seja parte lógica do heap, implementações simples podem optar por não coletar ou compactar o lixo". No entanto, é claro que o jconsole mostra o Cache de Código e a Geração Permanente como Não Heap, o que parece contradizer a especificação. Alguém pode fornecer mais esclarecimentos sobre essa contradição?
James Bloom
@ JamesBloom - eu queria saber o mesmo. Mesmo que a definição básica declare qual pool de memória pertence a qual tipo (heap / não heap), ela pode mudar de estado explicitamente?
precisa saber é o seguinte
2
o documento foi copiado de maneira semelhante a partir de: docs.intergral.com/pages/viewpage.action?pageId=22478944 O documento contém algumas outras informações boas sobre a JVM, que valem uma visita
Steve Siebert
1
Apesar de muitos votos positivos, na verdade não é uma resposta tão significativa. Por exemplo, o que significa "objetos que sobreviveram à coleta de lixo do espaço do Éden"? Esses objetos são movidos do Eden para o Survivor Space após a sobrevivência, ou o espaço no Eden é considerado como espaço do Survivor? E a coleta de lixo em piscinas que não sejam o espaço Eden, isso acontece? Totalmente não está claro.
Mikhail Batcer 11/03/16
e não se esqueça de pilha (no lado não-heap) :)
desdentado Seer
70

A nova palavra-chave aloca memória no heap Java. O heap é o pool principal de memória, acessível a todo o aplicativo. Se não houver memória suficiente disponível para alocar para esse objeto, a JVM tentará recuperar alguma memória da pilha com uma coleta de lixo. Se ainda não conseguir obter memória suficiente, um OutOfMemoryError será lançado e a JVM será encerrada.

O heap é dividido em várias seções diferentes, chamadas gerações. À medida que os objetos sobrevivem a mais coletas de lixo, eles são promovidos em diferentes gerações. As gerações mais velhas não são coletadas com frequência. Como esses objetos já provaram ter uma vida útil mais longa, é menos provável que sejam coletados como lixo.

Quando os objetos são construídos pela primeira vez, eles são alocados no Espaço Eden. Se sobreviverem a uma coleta de lixo, serão promovidos ao Survivor Space e, se viverem o suficiente por lá, serão alocados à Geração Tenured. Essa geração é coletada com muito menos frequência.

Há também uma quarta geração, chamada Geração Permanente, ou PermGen. Os objetos que residem aqui não são elegíveis para coleta de lixo e geralmente contêm um estado imutável necessário para a execução da JVM, como definições de classe e o conjunto constante de String. Observe que o espaço PermGen está planejado para ser removido do Java 8 e será substituído por um novo espaço chamado Metaspace, que será mantido na memória nativa. referência: http://www.programcreek.com/2013/04/jvm-run-time-data-areas/

insira a descrição da imagem aqui insira a descrição da imagem aqui

Pythoner
fonte
O diagrama parece muito auto-explicativo ... Isso é válido para qualquer algoritmo de GC. G1 tem conjunto diferente.
Venkateswara Rao
@ Pythoner Acho que a bandeira em roxo escuro deve ser -XX:PermSizee não -XX:MaxPermSizecomo já está definida acima disso.
Anurag
35

Com o Java8, a região não heap não contém mais PermGen, mas o Metaspace, que é uma grande mudança no Java8, deve se livrar dos erros de falta de memória com o java, pois o tamanho do metasspace pode ser aumentado dependendo do espaço exigido pelo jvm para os dados da classe.

user2767149
fonte
1
Na verdade, existe metasspace e espaço de classe: docs.oracle.com/javase/8/docs/technotes/guides/vm/gctuning/…
mrswadge
23

A memória de pilha Java faz parte da memória alocada à JVM pelo sistema operacional.

Os objetos residem em uma área chamada heap. O heap é criado quando a JVM é inicializada e pode aumentar ou diminuir de tamanho enquanto o aplicativo é executado. Quando a pilha fica cheia, o lixo é coletado.

insira a descrição da imagem aqui

Você pode encontrar mais detalhes sobre o Eden Space, Survivor Space, Tenured Space e Permanent Generation na pergunta SE abaixo:

Geração jovem, titular e permanente

O PermGen foi substituído pelo Metaspace desde o lançamento do Java 8.

Em relação às suas consultas:

  1. Eden Space, Survivor Space e Tenured Space fazem parte da memória heap
  2. Metaspace e Cache de Código fazem parte da memória não-heap.

Codecache: A Java Virtual Machine (JVM) gera código nativo e o armazena em uma área de memória chamada codecache. A JVM gera código nativo por vários motivos, incluindo o loop do interpretador gerado dinamicamente, os stubs Java Native Interface (JNI) e os métodos Java que são compilados no código nativo pelo compilador just-in-time (JIT). O JIT é de longe o maior usuário do codecache.

Ravindra babu
fonte