Terminologia de heap Java: gerações jovens, velhas e permanentes?

318

Estou tentando entender quais são os conceitos de gerações jovens , velhas e permanentes na terminologia de heap Java e, mais especificamente, nas interações entre as três gerações.

Minhas perguntas são:

  • Qual é a geração jovem?
  • Qual é a geração antiga?
  • Qual é a geração permanente?
  • Como as três gerações interagem / se relacionam?
knorv
fonte
Supondo que você esteja falando do Sun JDK / OpenJDK, consulte a página no site do OpenJDK em Storage Management . Existem alguns links para obter ainda mais informações na parte inferior.
Nicholas Riley
1
também relacionado com esta questão "geração tenured"
gstackoverflow

Respostas:

304

Isso parece um mal-entendido comum. Na JVM da Oracle, a geração permanente não faz parte do heap. É um espaço separado para definições de classe e dados relacionados. No Java 6 e versões anteriores, as cadeias internas também eram armazenadas na geração permanente. No Java 7, cadeias internas são armazenadas no heap do objeto principal.

Aqui está um bom post sobre geração permanente .

Gosto das descrições fornecidas para cada espaço no guia da Oracle no JConsole :

Para a VM Java HotSpot, os conjuntos de memórias para coleta de lixo serial são os seguintes.

  • Eden Space (heap): o pool do qual a memória é inicialmente alocada para a maioria dos objetos.
  • Espaço do Sobrevivente (pilha): o pool que contém objetos que sobreviveram à coleta de lixo do espaço Eden.
  • Geração Tenured (heap): o pool que contém objetos que existem há algum tempo no espaço sobrevivente.
  • Geração permanente (não heap): 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 (não heap): 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.

Java usa coleta de lixo geracional. Isso significa que, se você tiver um objeto foo (que é uma instância de alguma classe), mais eventos de coleta de lixo sobreviverão (se ainda houver referências a ele), mais ele será promovido. Começa na geração jovem (que em si é dividida em vários espaços - Eden e Survivor) e acabaria na geração ocupada se sobrevivesse por tempo suficiente.

Joshua McKinnon
fonte
2
Acredito que, a partir do Java 7, as strings não sejam mais internadas na geração permanente.
Tim Goodman
Você está certo, estou surpreso que isso tenha sobrevivido tanto tempo antes de uma menção. Então, em Java 8 geração permanente será substituído por metaspace (embora eu não tenho certeza de como diferente este será realmente, além de ser ilimitado por padrão)
Joshua McKinnon
9
Josué - "velho" é sinônimo de "titular" e "novo" é sinônimo de "sobrevivente?"
joadha
1
a perm gen é aplicável apenas antes de Java 8.
lwpro2
2
Caso você ainda esteja esperando uma resposta, sim, você está certo @joadha. Confira este link: codeahoy.com/2017/08/06/basics-of-java-garbage-collection
recepinanc
197

O Heap é dividido em gerações jovens e velhas da seguinte maneira:

Geração jovem : É o local onde moramos por um curto período e divididos em dois espaços:

  • Eden Space : quando o objeto é criado usando a nova memória de palavra-chave alocada neste espaço.
  • Espaço do Sobrevivente : Este é o pool que contém objetos que sobreviveram após a coleta de lixo java do espaço Eden.

Geração antiga : esse pool basicamente contém espaço virtual e reservado (reservado) e manterá os objetos que sobreviveram após a coleta de lixo da Geração Jovem.

  • Espaço Ocupado: Este conjunto de memórias contém objetos que sobreviveram após várias coletas de lixo significa objetos que sobreviveram após a coleta de lixo do espaço Survivor.

Geração permanente: esse conjunto de memórias, como o nome também diz, contém informações permanentes sobre metadados e descritores de classe, portanto o espaço PermGen sempre fica reservado para classes e aqueles que estão vinculados às classes, por exemplo, membros estáticos.

Atualização do Java8: PermGen é substituído pelo Metaspace, que é muito semelhante.
A principal diferença é que o Metaspace redimensiona dinamicamente, ou seja, ele pode se expandir em tempo de execução.
Espaço Java Metaspace: ilimitado (padrão)

Cache de código (virtual ou reservado): se você estiver usando o HotSpot Java VM, isso inclui a área de cache de código que contém a memória que será usada para compilação e armazenamento do código nativo.

insira a descrição da imagem aqui

Cortesia

Premraj
fonte
@Premraj, o que significa o Metaspace redimensionar dinamicamente, isto é, ele pode se expandir em tempo de execução. ? A única diferença que, por padrão, não tem fronteira?
Gstackoverflow
1
excelente ... posso saber onde a área do método, o nativestack e o pool constante de tempo de execução residem nessa imagem? e o que eles mantêm em conformidade?
se o cache de código for usado para o código do método nativo, o que a pilha do método nativo (cada thread terá um) terá?
49

Qual é a geração jovem?

A Geração Jovem é onde todos os novos objetos são alocados e envelhecidos. Quando a geração jovem se enche, isso causa uma pequena coleta de lixo. Uma geração jovem cheia de objetos mortos é coletada muito rapidamente. Alguns objetos sobreviventes são envelhecidos e, eventualmente, passam para a geração antiga.

Qual é a geração antiga?

A geração antiga é usada para armazenar objetos que sobreviveram por muito tempo. Normalmente, um limite é definido para o objeto de geração jovem e, quando essa idade é atingida, o objeto é movido para a geração antiga. Eventualmente, a geração antiga precisa ser coletada. Esse evento é chamado de coleta de lixo principal

Qual é a geração permanente?

A geração Permanente contém metadados exigidos pela JVM para descrever as classes e métodos utilizados no aplicativo. A geração permanente é preenchida pela JVM em tempo de execução com base nas classes em uso pelo aplicativo.

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

Os parâmetros PermSize e MaxPermSize serão ignorados agora

Como as três gerações interagem / se relacionam?

insira a descrição da imagem aqui

Artigo de tutorial sobre fonte de imagem e oracle technetwork: http://www.oracle.com/webfolder/technetwork/tutorials/obe/java/gc01/index.html

" O processo geral de coleta de lixo " no artigo acima explica as interações entre eles com muitos diagramas.

Dê uma olhada no diagrama resumido:

insira a descrição da imagem aqui

Ravindra babu
fonte
excelente ... posso saber onde a área do método, o nativestack e o pool constante de tempo de execução residem nessa imagem? e o que eles mantêm em conformidade?
consulte docs.oracle.com/javase/specs/jvms/se7/html/jvms-2.html para obter mais detalhes. A área do método é criada na inicialização da máquina virtual. Embora a área do método faça parte logicamente do heap, implementações simples podem optar por não coletar ou compactar o lixo. Cada pool constante de tempo de execução é alocado a partir da área método do Java Virtual Machine
Ravindra babu
você tem certeza ... você está lendo que faz parte do espaço permanente (que não é heap)? journaldev.com/2856/…
Documentação do Oracle é mais autêntica
Ravindra Babu
O limite está definido para o objeto de geração jovem em unidades de tempo (por exemplo, ms)? ou rodadas de GC?
Muito objetivo
16

A máquina virtual Java é organizada em três gerações: uma geração jovem, uma geração antiga e uma geração permanente. A maioria dos objetos é alocada inicialmente na geração jovem. A geração antiga contém objetos que sobreviveram a um certo número de coleções da geração jovem, além de alguns objetos grandes que podem ser alocados diretamente na geração antiga. A geração permanente mantém objetos que a JVM acha conveniente gerenciar o coletor de lixo, como objetos que descrevem classes e métodos, bem como as próprias classes e métodos.

Mark R
fonte
1

A memória no SunHotSpot JVM está organizada em três gerações: geração jovem, geração antiga e geração permanente.

  • Geração jovem: os objetos recém-criados são alocados para a geração jovem.
  • Geração antiga: se o novo objeto solicitar um espaço de heap maior, ele será alocado diretamente no antigo gen. Além disso, objetos que sobreviveram a alguns ciclos de GC são promovidos para a geração antiga, ou seja, objetos de vida longa abrigam-se na geração antiga.
  • Geração permanente: a geração permanente mantém objetos que a JVM acha conveniente gerenciar o coletor de lixo, como objetos que descrevem classes e métodos, bem como as próprias classes e métodos.

FYI: A geração permanente não é considerada parte do heap Java.

Como as três gerações interagem / se relacionam? Objetos (exceto os grandes) são primeiramente alocados à geração jovem. Se um objeto permanecer vivo depois de x não. dos ciclos de coleta de lixo, ele é promovido para o antigo / tenured gen. Portanto, podemos dizer que a geração jovem contém os objetos de vida curta, enquanto a geração antiga contém os objetos que têm uma vida longa. A geração permanente não interage com as outras duas gerações.

KrityAg
fonte