Pergunta

Ultimamente tenho lido muito sobre esquemas de alocação de memória em java, e tem surgido muitas dúvidas conforme tenho lido em diversas fontes.Reuni meus conceitos e gostaria de analisar todos os pontos e comentá-los.Fiquei sabendo que a alocação de memória é específica da JVM, então devo dizer de antemão que minha pergunta é específica da Sun.

  1. As classes (carregadas pelos classloaders) vão para uma área especial no heap:Geração Permanente
  2. Todas as informações relacionadas a uma classe como nome da classe, matrizes de objetos associadas à classe, objetos internos usados ​​​​pela JVM (como java/lang/Object) e informações de otimização vão para a área de Geração Permanente.
  3. Todas as variáveis ​​de membros estáticos são mantidas novamente na área Geração Permanente.
  4. Os objetos vão para uma pilha diferente:Geração jovem
  5. Existe apenas uma cópia de cada método por classe, seja o método estático ou não estático.Essa cópia é colocada na área de Geração Permanente.Para métodos não estáticos, todos os parâmetros e variáveis ​​locais vão para a pilha - e sempre que houver uma invocação concreta desse método, obteremos um novo quadro de pilha associado a ele.Não tenho certeza de onde as variáveis ​​locais de um método estático estão armazenadas.Eles estão na pilha de Geração Permanente?Ou apenas a referência deles é armazenada na área de Geração Permanente, e a cópia real está em outro lugar (Onde?)
  6. Também não tenho certeza de onde o tipo de retorno de um método é armazenado.
  7. Se os objetos (na geração mais jovem) precisarem usar um membro estático (na geração permanente), eles receberão uma referência ao membro estático && e receberão espaço de memória suficiente para armazenar o tipo de retorno do método, etc.

Obrigado por passar por isso!

Foi útil?

Solução

Primeiro, como já deve estar claro para você, há muito poucas pessoas que podem confirmar essas respostas com base no conhecimento de primeira mão.Muito poucas pessoas trabalharam em JVMs HotSpot recentes ou as estudaram com a profundidade necessária para realmente saber.A maioria das pessoas aqui (inclusive eu) está respondendo com base em coisas que viram escritas em outros lugares ou no que inferiram.Normalmente o que está escrito aqui, ou em vários artigos e páginas web, é baseado em outras fontes que podem ou não ser definitivas.Muitas vezes é simplificado, impreciso ou simplesmente errado.

Se você deseja uma confirmação definitiva de suas respostas, você realmente precisa baixar o código-fonte do OpenJDK ...e faça sua própria pesquisa lendo e compreendendo o código-fonte.Fazer perguntas sobre SO ou pesquisar artigos aleatórios na web não é uma técnica sólida de pesquisa acadêmica.

Tendo dito isto ...

1) As classes (carregadas pelos classloaders) vão para uma área especial no heap:Geração Permanente.

AFAIK, sim.(Atualizar:Veja abaixo.)

2) Todas as informações relacionadas a uma classe como nome da classe, arrays de objetos associados à classe, objetos internos usados ​​pela JVM (como java/lang/Object) e informações de otimização vão para a área de Geração Permanente.

Mais ou menos, sim.Não tenho certeza do que você quer dizer com algumas dessas coisas.Suponho que "objetos internos usados ​​pela JVM (como java/lang/Object)" significa descritores de classe internos da JVM.

3) Todas as variáveis ​​de membros estáticos são mantidas novamente na área de Geração Permanente.

As próprias variáveis ​​sim.Essas variáveis ​​(como todas as variáveis ​​Java) conterão valores primitivos ou referências de objetos.No entanto, embora as variáveis ​​de membro estático estejam em um quadro alocado no heap permgen, os objetos/matrizes referidos por essas variáveis ​​podem ser alocados em qualquer pilha.

4) Os objetos vão para uma pilha diferente:Geração jovem

Não necessariamente.Objetos grandes poderia ser alocado diretamente na geração efetiva.

5) Existe apenas uma cópia de cada método por classe, seja o método estático ou não estático.Essa cópia é colocada na área de Geração Permanente.

Supondo que você esteja se referindo ao código do método, então AFAIK sim.Pode ser um pouco mais complicado.Por exemplo, esse código pode existir em bytecode e/ou formas de código nativo em momentos diferentes durante a vida da JVM.

...Para métodos não estáticos, todos os parâmetros e variáveis ​​locais vão para a pilha - e sempre que houver uma invocação concreta desse método, obteremos um novo quadro de pilha associado a ele.

Sim.

...Não tenho certeza de onde as variáveis ​​locais de um método estático estão armazenadas.Eles estão na pilha de Geração Permanente?Ou apenas a referência deles é armazenada na área de Geração Permanente, e a cópia real está em outro lugar (Onde?)

Não.Elas são armazenadas na pilha, assim como as variáveis ​​locais em métodos não estáticos.

6) Também não tenho certeza de onde o tipo de retorno de um método é armazenado.

Se você quer dizer o valor retornado por uma chamada de método (não nulo), então ele é retornado na pilha ou em um registro de máquina.Se for retornado na pilha, serão necessárias 1 ou duas palavras, dependendo do tipo de retorno.

7) Se os objetos (na geração mais jovem) precisarem usar um membro estático (na geração permanente), eles recebem uma referência ao membro estático && recebem espaço de memória suficiente para armazenar o tipo de retorno do método, etc. .

Isso é impreciso (ou pelo menos você não está se expressando com clareza).

Se algum método acessa uma variável de membro estático, o que ele obtém é um valor primitivo ou um objeto referência.Isso pode ser atribuído a uma variável ou parâmetro local (existente), atribuído a um membro estático ou não estático (existente), atribuído a um elemento (existente) de uma matriz alocada anteriormente ou simplesmente usado e descartado.

  • Em nenhum caso novo o armazenamento precisa ser alocado para conter uma referência ou um valor primitivo.

  • Normalmente, uma palavra de memória é tudo o que é necessário para armazenar uma referência de objeto ou array, e um valor primitivo normalmente ocupa uma ou duas palavras, dependendo da arquitetura de hardware.

  • Em nenhum caso o espaço precisa ser alocado pelo chamador para armazenar algum objeto/array retornado por um método.Em Java, objetos e arrays são sempre retornados usando semântica de passagem por valor...mas o valor retornado é uma referência de objeto ou matriz.

ATUALIZAR

A partir do Java 8, o espaço PermGen foi substituído pelo Metaspace.Para obter mais informações, consulte estes recursos:

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top