1. análise de memória Java
Vamos falar sobre o carregamento de classe e, em seguida, usar uma instância para analisar essa memória
2. Processo de carregamento de classe
Quando o programa usa ativamente uma classe, se a classe não tiver sido carregada na memória, o sistema inicializará a
classe através das três etapas a seguir: Carregamento de classe e entendimento do ClassLoader
[1] Carregamento: Conteúdo do bytecode do arquivo de classe Carregue-o na memória e converta esses dados estáticos na estrutura de dados de tempo de execução da área do método e gere um objeto java.lang.Class representando este
link de classe [2]: mescle o código binário da classe java no estado de execução da JVM Processo em
- Verificação: verifique se as informações da classe carregada estão em conformidade com a especificação da JVM e se não há problemas de segurança
- Preparação: Aloque oficialmente a memória para variáveis de classe (estáticas) e defina o estágio de atravessar o valor inicial padrão.Estas memórias serão alocadas na área de método
- Resolução: o processo de substituição da referência de símbolo (nome constante) no pool de constantes da máquina virtual por uma referência direta (endereço)
[3] Inicialização:
- O processo de execução do método construtor de classe (). O método construtor de classe () é gerado pelo compilador coletando ativamente as ações de atribuição de todas as variáveis de classe na classe e mesclando as instruções no bloco de código estático . (O construtor da classe constrói as informações da classe, não o construtor que constrói os objetos dessa classe)
- Ao inicializar uma classe, se você achar que a classe pai não foi inicializada, será necessário acionar a inicialização da classe pai primeiro
- A oportunidade virtual garante que o método clint () de uma classe seja bloqueado e sincronizado corretamente em um ambiente multithread
Depois de muitas teorias acima, vamos entender esse processo através de um exemplo específico
package com.gs.reflection;
//测试类的加载
public class Test05 {
public static void main(String[] args) {
A a = new A();
System.out.println(A.m);
}
}
class A{
static{
System.out.println("A类静态代码初始化");
m = 300;
}
static int m = 100;
public A(){
System.out.println("A类的无参构造器初始化");
}
}
Resultados do código acima:
analise os resultados:
- Carregar: quando o código é executado, primeiro carregue o conteúdo do bytecode dos arquivos das classes A e Test05 na memória e coloque os dados relevantes na área do método; finalmente, eles gerarão a classe java.lang.Class correspondente no heap.
- Vincule, atribua valores iniciais a blocos de código estáticos e faça referência direta a constantes => aqui corresponde ao código acima é redefinir a variável estática m para o valor inicial de 0
- Inicialização, podemos ver pela análise acima que é primeiro executar as ações de atribuição de todas as variáveis de classe e as instruções de bloco de código estático e, em seguida, inicializar.
Portanto, sua sequência de execução é:
[1] clinit () {
System.out.println ("Inicialização de código estático de classe A");
m = 300;
m = 100;
}
[2] Inicialização de classe A
Gráfico de análise de memória relacionada
O conteúdo acima refere-se às anotações e reflexões em Java