Partição de memória dinâmica da JVM e algoritmo de coleta de lixo

Partição de memória dinâmica da JVM e algoritmo de coleta de lixo - Resumo da leitura "Entendimento aprofundado da Java Virtual Machine"

Para obter o gerenciamento dinâmico dos dados de tempo de execução, a máquina virtual Java implementa um conjunto de mecanismos de gerenciamento de memória: primeiro, a memória de tempo de execução é dividida, um modelo conceitual de divisão de memória é especificado e um algoritmo de coleta de lixo é fornecido para uma área específica. Para que os programadores Java não precisem se preocupar com os detalhes do gerenciamento de memória, mas tudo tem vantagens e desvantagens. Quando há problemas relacionados ao processamento da memória, precisamos entender os detalhes subjacentes da implementação, para que possamos localizar e resolver rapidamente o problema.

Este artigo descreve três partes:
- zoneamento memória de tempo de execução
- o objeto de armazenamento e acesso
- algoritmo de coleta de lixo


Divisão de área de memória de tempo de execução

É necessário enfatizar novamente: a divisão da área de memória mencionada neste artigo é um resumo do modelo conceitual na especificação da JVM.Pode haver diferenças nos diferentes produtos de implementação da JVM, como a implementação da máquina virtual HotSport. A pilha de métodos é implementada de maneira uniforme.

Partição de memória JVM
Diferente do que pensávamos antes, a memória é simplesmente dividida em duas partes: pilha e pilha. Como pode ser visto na figura, a área de dados de tempo de execução da JVM é dividida principalmente em cinco partes: contador de programa, pilha de máquina virtual, pilha de método local, heap Java e área de método. Os detalhes estão descritos abaixo.

  1. O contador de programa
    pode ser entendido como o indicador de número de linha, a instrução de controlo de fluxo de execução principal, isto é realizar uma sequência de base, ramificado, cíclico declaração três fluxo. Como cada processador pode executar apenas uma determinada instrução em um segmento por vez, cada segmento precisa salvar um contador de programa do segmento atual.

  2. VM pilha
    para cada chamada de método para o quadro da pilha como uma unidade, através da pilha, a pilha de operação chamada de método processo de aplicação. O quadro da pilha armazena informações como tabelas de variáveis ​​locais, pilhas de operandos, links dinâmicos e saídas de método.

  3. método nativo pilhas
    papel com a pilha de máquina virtual, mas as pilhas método nativo para uso métodos principalmente nativas.

  4. Heap
    é usado principalmente para armazenar objetos de dados e matrizes, de acordo com a estratégia de coleta de lixo, dividido em nova geração e da era antiga, o Cenozóico é dividido em Éden, FromSurvior, ToSurvior. Também existem outros métodos de classificação, por exemplo, do ponto de vista da alocação de memória, ele pode ser dividido em vários buffer de alocação privada de encadeamento TLAB (Buffer de Alocação Local de Encadeamento). Além disso, a máquina virtual Hotspot coloca a área do método na memória heap Java e a gerencia em uma geração permanente, além de escrever menos sobre o método de coleta de lixo da área do método, mas o efeito não é satisfatório.

  5. Métodos distrito de
    informações de classe método de armazenamento área principal da carga da máquina virtual, piscina constante, variáveis estáticas, o compilador tempo para compilar o código e outros dados.

Além disso, a memória direta marcada na figura não é a área de memória definida na especificação da JVM, mas a JVM pode acessar a memória fora do heap através do NIO para chamar a biblioteca de funções local para melhorar a eficiência da chamada. Esta parte não é limitada pelo tamanho da memória da JVM, mas Ele ainda é limitado pelo tamanho total da memória da máquina, portanto, ao dividir a memória do programa java, ele não pode ocupar toda a memória da máquina.Você precisa considerar as necessidades dessa parte da memória.


Criação e acesso a objetos

Inclui principalmente a estrutura de armazenamento, processo de criação e método de acesso a objetos.
Criação e acesso a objetos

O objeto é armazenado principalmente na memória heap e seu processo de criação é dividido principalmente em cinco etapas:
1. Verifique se a classe está carregada, se não carregada, e execute o processo de carregamento da classe; após o término do carregamento da classe, você pode determinar o tamanho da memória do objeto;
2 Aloque memória, conforme a área da memória seja regular, ela será dividida em "colisão do ponteiro" (Bump the Pointer) e "free list" (Free List) dois métodos, a agulha de colisão do ponteiro se refere à divisão da memória devido à regulação da memória, mova apenas o ponteiro da memória Dessa forma, a lista livre significa o caminho para registrar o uso de blocos de memória através de uma tabela de registros. Se a área de memória é regular ou não, é determinada pelo algoritmo de coleta de lixo;
3. Inicialize o valor 0, e é por isso que o atributo tem o valor padrão após a criação do nosso objeto;
4. Defina o cabeçalho do objeto, defina os dados de tempo de execução do objeto de acordo com o estado diferente do objeto;
5. Execute o método init da classe Java.

Depois que o objeto é criado, sua estrutura de dados na memória inclui principalmente informações de cabeçalho de objeto e ponteiro de classe. Se o objeto for uma matriz, você também precisará armazenar dados de comprimento da matriz.

Os métodos de acesso a objetos são divididos em identificadores e ponteiros diretos
1. Acesso ao identificador: um pool de identificadores é dividido no heap Java. A variável de tipo de referência na tabela de variáveis ​​locais do espaço de pilha aponta para o identificador.O identificador inclui o endereço e a área do método do objeto. O endereço do tipo de dados.
2. Ponteiro direto: a variável do tipo de referência aponta diretamente para o endereço da memória do objeto na pilha e o endereço dos dados do tipo precisa ser armazenado no objeto.
Ambos os métodos têm suas próprias vantagens e desvantagens. Para a operação de objetos em movimento, o método handle apenas precisa alterar o endereço em que o identificador está armazenado. Não há necessidade de alterar os dados de referência, mas ocupa mais memória e adiciona a sobrecarga do posicionamento do ponteiro ao acessar o objeto; O método do ponteiro é mais eficiente, mas são necessárias mais operações ao acessar dados de tipo e mover objetos. O HotSpot usa acesso direto ao ponteiro.


Algoritmo de coleta de lixo

A coleta de lixo foi antecipada antes do Java, e essa parte inclui principalmente três perguntas: Que memória é recuperada? Quando será reciclado? Como reciclar?
Algoritmo de coleta de lixo

Que memória é recuperada?

O algoritmo de análise de acessibilidade é usado em Java para atingir o objetivo de avaliar se um objeto está ativo.O Java começa a enumerar objetos de uma série de nós de objetos chamados GC Roots. O caminho percorrido é chamado de "cadeia de referência". Quando nenhuma cadeia de referência está conectada, o objeto é determinado como reciclável.
Além de referências e sem referências, existem alguns estados intermediários para referência entre objetos. O tipo de referência foi estendido desde o JDK 1.2 para descrever alguns objetos no estado "sem gosto por comida, uma vergonha por desistir", semelhante à aplicação de armazenamento em cache no sistema. De acordo com a força de referência de forte a fraca, ele é dividido em quatro tipos, que serão tratados de maneira diferente ao executar análises de acessibilidade e recuperação de memória para diferentes tipos de referências.
1. Referência forte: refere-se à referência geral existente, semelhante a Object obj = new Object ();
2. Referência flexível: objetos não essenciais, seus objetos associados serão reciclados duas vezes antes que ocorra a exceção de estouro de memória, JDK fornece implementação da classe SoftReference;
3. Referência fraca: também descreve objetos não essenciais, na próxima coleta de lixo, independentemente de a memória ser suficiente, o objeto de referência será reciclado; o JDK fornece a implementação da classe WeakReference;
4. Referência virtual: o ciclo de vida do objeto não é Isso causa um impacto.Você receberá uma notificação do sistema durante a coleta de lixo do objeto de referência dessa classe.O JDK fornece a implementação da classe PhantomReference.

Para objetos inacessíveis, ainda há uma chance de sobrevivência. Durante as duas marcações de coleta de lixo, um filtro será executado para a primeira marcação. Se o objeto reescrever o método finalize (), ele será adicionado à fila da fila de espera. A JVM é executada por meio de um encadeamento finalizador de baixa prioridade auto-construído. Se o método finalize () do objeto se referir à cadeia de referência GC Roots, ele poderá evitar a reciclagem, mas a JVM não garante que o método finalize () possa ser executado com êxito.Este método é apenas para desenvolvedores Java C ++ quando o Java nasceu. É mais fácil aceitá-lo.

Quando será reciclado?

STW (Stop The World): esse nome parece legal, mas não é uma coisa boa ... Refere-se à necessidade de referências entre objetos quando a JVM enumera o nó raiz (determinação da cadeia de referência de raízes do GC na análise de acessibilidade) Manter uma condição consistente (por exemplo, um objeto acabou de ser criado e não foi associado à sua variável de tipo de referência. Nesse momento, a análise de acessibilidade pode ser realizada para identificá-lo como um objeto reciclável ...), o que requer a necessidade de Parar todos os encadeamentos de execução Java é chamado STW.
Na máquina virtual HotSpot, uma estrutura de dados OopMap é usada para armazenar relacionamentos de referência para obter GC preciso (a JVM conhece o tipo específico de dados no local da memória), portanto, não é necessário verificar o contexto completo e o local de referência global. Existem muitas instruções que causam alterações no OopMap. Somente quando o encadeamento Java é executado no SafePoint (ponto de segurança tem o recurso de permitir que o programa seja executado por um longo tempo) e os dados do OopMap são temporariamente corrigidos, o GC pode ser temporariamente corrigido, o GC pode ser executado. Esses locais incluem chamadas de método e saltos de loop. , Saltos anormais, etc.
Há duas maneiras de parar o programa em um ponto seguro: interrupção preemptiva, interrupção ativa, interrupção preemptiva significa que a JVM para diretamente todos os encadeamentos de execução e, se não houver encadeamentos no ponto seguro, ele será restaurado. Deixe-o continuar em um ponto seguro e, em seguida, pare; a interrupção ativa é definir um sinalizador de interrupção, e cada thread pesquisa esse sinalizador quando é executado.Se o sinalizador for verdadeiro, a interrupção será suspensa.
Para o encadeamento no estado Suspenso ou Bloqueado, ele não pode responder à solicitação de interrupção da JVM e é executado em um ponto seguro.Neste momento, o SafeRegion (área segura - um trecho de código de área segura, o relacionamento de referência não muda) precisa ser usado. Quando o encadeamento inserir esse código No momento, ele se identifica como entrando em uma área segura e a JVM inicia o GC, independentemente do encadeamento no SafeRegion. Quando o encadeamento sai do SafeRegion, é necessário verificar se a enumeração do nó raiz está concluída e pode sair após o término.

Como reciclar?

  1. Mark - varrer
    é o algoritmo de coleta mais básico, os outros dois são baseadas neste algoritmo. O algoritmo é dividido em duas etapas: marcação e limpeza. Ao determinar qual memória reciclar, o processo de marcação é mencionado duas vezes para marcar os objetos a serem reciclados. Após a conclusão da marcação, os objetos a serem reciclados são limpos. Ele tem problemas de baixa eficiência de execução e propenso a fragmentação de memória.

  2. Cópia
    depois para a eficiência, algoritmo de replicação área de memória é dividida em um espaço Éden, duas áreas sobrevivente menores, cada um com apenas um Éden, uma área de memória do sobrevivente, coleta de lixo, copie os objetos vivos para outro dentro da faixa Survivor , Se o objeto sobrevivente ocupar mais espaço do que outra área de memória do Survivor, ele será alocado ao intervalo de memória garantida (o HotSpot refere-se especificamente à geração antiga) .Se o
    algoritmo de replicação tiver uma alta taxa de sobrevivência, a eficiência da replicação é baixa e é necessário espaço adicional na memória para garantir As características são adequadas para a nova geração de reciclagem de memória.

  3. Mark - terminando
    o processo de etiquetagem e método de marcação - algoritmo de varredura como o processo de acabamento é para passar para a final dos objetos vivos e objetos fora dos limites do clean-up direto, resolver o problema da fragmentação de memória para a era antiga.

O coletor de lixo na máquina virtual do HotSpot é classificado de acordo com as características dos algoritmos, simultaneidade e paralelismo da coleta de lixo, e não o apresentarei aqui.

Sumário

Este artigo fornece uma introdução detalhada ao modelo conceitual da memória de tempo de execução da máquina virtual Java e detalha o processo de criação do objeto, a estrutura de dados do objeto e o local de acesso na memória heap. Finalmente, para o algoritmo de coleta de lixo, descreveremos quais objetos, quando e como reciclar. Após concluir esse conteúdo, temos um entendimento teórico da estrutura de memória e coleta de lixo da JVM. Essas teorias e princípios estão em diferentes coletores de lixo, Os parâmetros da JVM não são fixos sob diferentes configurações e outras condições, e precisamos entendê-los e aplicá-los de acordo com a situação real.

Publicado 159 artigos originais · elogiou 225 · 210.000 visualizações

Acho que você gosta

Origin blog.csdn.net/lyg673770712/article/details/80837046
Recomendado
Clasificación