Perguntas de alta frequência da entrevista JVM

Índice

1. Processo e thread

 Dois, processo JVM

3.JVM

Divisão de área de memória JVM

Carregamento de classe JVM

Processo de carregamento de classe

 Coleta de lixo JVM (GC)

 1. Na coleta de lixo, o que é reciclado?

 2. Como determinar se o objeto precisa ser reciclado?

3. Após determinar os objetos a serem reciclados, como realizar a coleta de lixo?


1. Processo e thread

Antes de falar sobre essas questões da JVM, vamos revisar o relacionamento entre threads e processos

  • Um processo pode ser visto como o processo de execução de um programa. A execução de um programa requer recursos como tempo de CPU, espaço de memória, arquivos e E/S. O sistema operacional aloca esses recursos em unidades de processos, portanto, um processo é a unidade básica de alocação de recursos.
  • Threads pertencem ao processo e só podem estar ativos dentro do processo.Múltiplos threads compartilham os recursos pertencentes ao processo. Se o processo for considerado como uma coleção de tarefas que completam muitas funções, então um thread é um elemento de tarefa na coleção, responsável por funções específicas . Embora recursos como CPU, memória e E/S sejam alocados para processos, são os threads que realmente utilizam esses recursos e os executam na CPU, ou seja, threads que realmente completam as funções do programa.

Como o processo é o proprietário desses recursos, sua carga é muito pesada e as despesas gerais de tempo e espaço no processo de criação, alternância e exclusão de processos são muito grandes. Portanto, os atuais sistemas operacionais convencionais consideram o processo apenas como o proprietário do recurso e atribuem os atributos de agendamento e operação da CPU ao thread.

Por exemplo, abrir um programa de navegador gerará um processo correspondente. O processo do navegador contém muitos threads, como threads de solicitação HTTP, threads de E/S, threads de renderização e threads de resposta a eventos. O processo do navegador tem memória e recursos de E/S, etc., mas quando inserimos texto no navegador, é a E/S no processo do navegador que realmente usa os recursos de E/S para receber o texto que inserimos e processar o texto no thread CPU. /O. Ou seja, é o thread que realmente completa a função de entrada de texto do navegador.

 Muitos sistemas operacionais modernos permitem que um processo contenha vários threads, melhorando assim o paralelismo do programa e a utilização de recursos.

 Dois, processo JVM

Sabemos que a linguagem Java precisa rodar na JVM. Na verdade, a JVM também é um programa de software, o que significa que ao ser executado também criará um processo no sistema operacional, ou seja, um processo JVM, geralmente chamado de instância JVM . E o método principal que escrevemos é onde o thread principal do processo JVM está localizado.

Do ponto de vista do sistema operacional, o programa Java que costumamos dizer deve incluir a JVM e o código Java que escrevemos.

Quando terminarmos de escrever o código Java e compilá-lo em um arquivo de classe, use o comando Java para executar o método principal; ou inicie diretamente o método principal no IDE, o programa JVM será executado e o sistema operacional irá carregá-lo em a memória do disco e cria um processo JVM, então inicia o thread principal, e o thread principal chamará o método principal de uma determinada classe, então este thread principal é onde o método principal que escrevemos está localizado.

Na verdade, a própria JVM é um aplicativo multithread, mesmo que não criemos threads manualmente no código, o processo JVM não possui apenas um thread principal, mas também possui outros threads. Esses threads completam as funções da JVM, como o thread GC é responsável por reciclar objetos de lixo durante o uso da JVM. Após o início do processo JVM, deve haver threads como segue:

fio efeito
principal O thread principal executa o método principal da classe de inicialização que especificamos
Manipulador de referência thread que lida com referências
Finalizador O thread que chamou o método finalize do objeto
Despachante de Sinal Despacha threads que tratam de sinais enviados para a JVM
Anexar ouvinte O thread responsável por receber comandos externos

Até agora, sabemos que iniciar um programa Java é essencialmente iniciar um programa JVM e criar um processo JVM no sistema operacional. Este processo JVM receberá muitos recursos do sistema operacional, como memória, E/S e assim por diante. O processo JVM contém muitos threads. Esses threads compartilham os recursos alocados pelo processo JVM. Ao mesmo tempo, esses threads também são entidades executadas no núcleo da CPU e completam as funções da JVM.

Ao mesmo tempo, também podemos descobrir por meio de experimentos quantos programas Java são iniciados e quantos processos JVM (instâncias JVM) serão criados. Cada instância é independente e não afeta uma à outra, ou seja, um programa (um programa de software JVM) pode ser compartilhado por vários processos (criando vários processos JVM ou instâncias JVM)

3.JVM

Divisão de área de memória JVM

Em geral, a JVM pode ser dividida em quatro partes:

  • a pilha
  • amontoar
  • área de método
  • contador de programa

Todos devem estar familiarizados com variáveis ​​em java! As variáveis ​​são divididas em variáveis ​​globais, variáveis ​​locais, variáveis ​​estáticas

dica: Todos deveriam falar principalmente sobre pilha e heap na JVM aqui, que é diferente da pilha e heap no sistema operacional e da pilha e heap na estrutura de dados. Quando lhe perguntarem sobre pilhas e montes no futuro, você deve descobrir onde estão as pilhas e montes.

por exemplo

public class test {
    public int a; // 全局变量(也可叫做test这个类的成员变量)
    public static int b; // 静态变量
    public void method() {
        int c = 0; // 局部变量
        System.out.println("这是test这个类的一个普通成员方法");
    }
    public static void run() {
        System.out.println("这是一个静态方法!"); // 静态方法不需要借助实例化对象
    }
    public static void main(String[] args) {
        test test1 = new test(); // test1 是test类的一个实例化对象
        test test2 = new test(); // test2 是另一个实例化对象
    }
}
  1.  Nossas variáveis ​​locais são armazenadas na pilha. Variáveis ​​globais fazem parte de nossos novos objetos instanciados e são armazenadas na pilha. Variáveis ​​estáticas são especiais porque são armazenadas na área de método.
  2. Então, o que mais está em nossa pilha? Existe também o relacionamento de chamada entre os vários métodos da nossa classe.

De volta ao heap, percebemos que nossos novos objetos instanciados são armazenados no heap, e cada um de nossos objetos instanciados tem suas variáveis ​​​​e métodos correspondentes (ou seja, nossos métodos e variáveis ​​​​de membro). com os objetos.

E quanto a variáveis ​​estáticas e métodos estáticos?

Eles não pertencem aos objetos que instanciamos, eles existem quando nossa classe é criada e não dependem de objetos instanciados. Eles pertencem a objetos de classe e os colocamos na área de métodos como objetos de classe.

Então, o que há no objeto de classe?

Qual é o nome da classe include

Quem herda e implementa essas interfaces

Quais são os atributos, qual é o nome do atributo, qual é o tipo, qual é a permissão de acesso

Existe algum método, nome do método?Parâmetros? valor de retorno? permissão de acesso? Qual é a instrução dentro do método? O que é feito no método?

Resumindo, o objeto de classe descreve nossa classe como um todo. Uma classe pode ter vários objetos instanciados, mas existe apenas um objeto de classe (ou seja, cada variável estática e método estático possui apenas um em diferentes objetos instanciados).

vamos resumir

  • Pilha (chamar relacionamento entre métodos, variáveis ​​locais)
  • Heap (objetos instanciados: variáveis ​​globais (também chamadas de variáveis ​​de membro), métodos de membro)
  • Área de métodos (objetos de classe: variáveis ​​estáticas, métodos estáticos....)

Ah, a propósito, ainda temos o contador do programa

 Como dissemos acima, quando iniciamos um java e iniciamos o método principal, nosso programa JVM será executado, um processo JVM será criado e haverá vários threads responsáveis ​​por completar o trabalho da JVM. Então, eu gostaria de perguntar: cada tópico possui as quatro áreas acima?

Não, nossa área de método e heap possuem apenas uma cópia em todo o processo JAVA (vários threads no processo compartilham esse recurso), mas cada thread possui uma cópia do contador e da pilha do programa.

por que:

Recursos relacionados, como CPU do sistema operacional, são alocados para um processo, e todos os threads no processo compartilham todos os recursos do processo, e o thread é a unidade básica de execução.

Cada thread está executando seu próprio código e cada um é um fluxo de execução. Portanto, cada thread precisa saber qual instrução executar em seguida (a função do contador do programa)? Cada thread também precisa registrar a pilha de chamadas atual (há uma área de método)

Carregamento de classe JVM

Quando o programa Java é iniciado, é necessário permitir que a JVM leia o arquivo de classe na memória e execute uma série de trabalhos de acompanhamento.

Processo de carregamento de classe

1. Carregar Encontre o arquivo de classe, abra o arquivo, leia o arquivo e crie um objeto de classe vazio

2. Ligação

  • Validação - verifica se o formato do arquivo .class está em conformidade com os requisitos da especificação (descritos explicitamente na especificação JVM)
  • Preparação —— Aloque espaço de memória para variáveis ​​estáticas e preencha o espaço com valores 0.
  • Análise —— Inicialize a constante da string e substitua "referências conformes por referências diretas"

3. Inicialização

Inicialize os membros estáticos da classe e execute o bloco de código estático. Se a classe pai desta classe ainda não tiver sido carregada, a classe pai também deverá ser carregada

Na entrevista, a coisa favorita do entrevistador para testar é - "modelo de delegação parental" (descreve a fase de carregamento no carregamento da classe, vá para esses diretórios para encontrar os arquivos .class

Para entender o chamado modelo de delegação parental, precisamos saber : carregador de classes - um módulo especial na JVM, que é responsável por carregar classes e completar o trabalho de carregamento de classes.

 


 Coleta de lixo JVM (GC)

Você se lembra? Na linguagem C, solicitamos memória dinamicamente por meio de malloc (a memória aplicada está no heap) e precisamos liberar manualmente a memória (livre) após cada aplicação. Se não for lançado, causará sérios problemas, como vazamentos de memória.

Mas se esperarmos apenas que nossos programadores liberem memória manualmente, isso obviamente não será confiável.

Porque em Java a máquina é responsável por recuperar o espaço de memória que não é mais utilizado - esse mecanismo é chamado de mecanismo de recuperação de memória (coleta de lixo conhecida como GC)

 1. Na coleta de lixo, o que é reciclado?


 2. Como determinar se o objeto precisa ser reciclado?

 Então sabemos que a unidade de reciclagem é um objeto, então como determinamos especificamente que um objeto é lixo (não é mais usado)?

Há muitas maneiras de determinar se é lixo. Entre eles, o método de “análise alcançável” é usado principalmente em Java, e o método de “contagem de referência” é usado em outras linguagens de programação (como Python).

No livro "Compreensão aprofundada da máquina virtual Java", ambos os métodos são mencionados.

  • Então, se na entrevista nos perguntarem: No mecanismo de coleta de lixo, como julgar se o objeto é lixo? Você pode dizer ambos.
  • ​​​​Se você está perguntando: Como julgar se um objeto é lixo na JVM, você só precisa responder "análise de acessibilidade".

 contagem de referência

Use contadores adicionais para registrar quantas referências a um objeto apontam para ele.

Se você quiser usar um objeto, você precisa ter uma referência apontando para ele. Se a referência for inútil - a contagem de referências é 0, significa que o objeto não pode ser usado, ou seja, lixo que precisa ser reciclado.

Análise de acessibilidade (a abordagem que Java realmente adota)

Acessibilidade, o que você quer dizer?

É começar com algumas variáveis ​​​​especiais no código e, em seguida, acionar a partir do ponto inicial para ver se esses objetos podem ser acessados. Enquanto o objeto puder ser acessado, ele será marcado como “alcançável”, após completar uma rodada de marcação, o restante fica “inacessível”, ou seja, lixo a ser reciclado! ! !

Vamos explicar alguns dos substantivos acima

1. Que tipo de variável pode ser chamada de ponto de partida (GCRoot)?

1. Referências a objetos na tabela de variáveis ​​locais (variáveis ​​locais na pilha, existem várias pilhas, uma para cada thread, e há muitos quadros de pilha em cada pilha, e cada quadro de pilha tem sua própria superfície de variável local.)

Isso significa: todas as variáveis ​​em todas as tabelas de variáveis ​​locais de todas as pilhas e todos os quadros de pilha de todos os threads podem ser consideradas como GCRoot.

2. O objeto correspondente no pool constante

3. Na área de métodos, membros de tipos de referência estática

2. O que é “acessível”?


3. Após determinar os objetos a serem reciclados, como realizar a coleta de lixo?

Existem várias notas sobre o algoritmo clássico de coleta de lixo (estratégia)

1. Marcar-Limpar

2. Algoritmo de cópia (para resolver o problema de fragmentação de memória)

3. Marcação e classificação (semelhante à exclusão de elementos em uma tabela de sequência)

 

 4. Reciclagem geracional

 

Resumir:

  1. Na área do Éden , se os objetos recém-nascidos sobreviveram a uma rodada de GC ( uma rodada de GC e a maioria dos objetos foram reciclados, um pequeno número deles sobreviveu a uma rodada de GC ), coloque esses objetos sobreviventes na área de sobrevivência área ( Como há poucos objetos, o espaço na área de sobreviventes não é grande)
  2. Os objetos da área sobrevivente utilizam o algoritmo de cópia, pois o número é pequeno, não importa se metade da memória é desperdiçada.
  3. Os objetos da geração antiga utilizam o algoritmo de acabamento de marca, pois os objetos da geração antiga não são reciclados com frequência, podendo receber a sobrecarga causada pelo acabamento de marca

Revisitando a reciclagem geracional

 

 

4. Perguntas comuns sobre JVM

Julgamento das raízes do GC

Implementação da JVM

 carregador de classes

 Diferença entre coletor de lixo e algoritmo de coleta de lixo

Partição de memória JVM

Acho que você gosta

Origin blog.csdn.net/weixin_61061381/article/details/127526356
Recomendado
Clasificación