Cabeçalho de objeto JAVA de programação simultânea Java (incluindo máquina virtual de 32 bits e máquina virtual de 64 bits)

Por que aprender cabeçalhos de objeto Java

Aprender o cabeçalho do objeto Java é principalmente para compreender os princípios subjacentes da sincronização, o processo de atualização de bloqueio sincronizado e programação Java simultânea.
Insira a descrição da imagem aqui

Cabeçalho do objeto JAVA

Devido à ideia orientada a objetos do Java, um grande número de objetos de armazenamento são necessários na JVM. A fim de realizar algumas funções adicionais durante o armazenamento, alguns campos de marca precisam ser adicionados aos objetos para aprimorar as funções do objeto. Esses campos de marca constituem o cabeçalho do objeto.

Na máquina virtual HotSpot, o layout dos objetos armazenados na memória pode ser dividido em três áreas: cabeçalho do objeto (Cabeçalho), dados da instância (Dados da Instância) e preenchimento do alinhamento (Padding).
Ou seja, objeto JAVA = cabeçalho do objeto + dados da instância + preenchimento do objeto.

Dentre eles, o cabeçalho do objeto é composto por duas partes, uma parte é usada para armazenar seus próprios dados de tempo de execução, denominados Mark Word, e a outra parte é o ponteiro de tipo, e o objeto aponta para o ponteiro de metadados da classe.

Cabeçalho do objeto = Mark Word + tipo de ponteiro
(quando a compressão do ponteiro não está ativada)
Em um sistema de 32 bits, Mark Word = 4 bytes = 32 bits e cabeçalho do objeto = 8 bytes = 64 bits;
em um sistema de 64 bits, Mark Word = 8 bytes = 64 bits, cabeçalho do objeto = 16 bytes = 128 bits;

bytes são bytes e bits são bits. Portanto, no sistema de máquina virtual JVM de 32 bits, a parte Mark Word ocupa 4 bytes e a parte Klass Word também ocupa 4 bytes, portanto, o tamanho do cabeçalho do objeto é de 8 bytes. No sistema de máquina virtual JVM de 64 bits, a parte Mark Word ocupa 8 bytes e a parte Klass Word também ocupa 8 bytes, então o tamanho do cabeçalho do objeto é 16 bytes.

Cabeçalho de objeto de máquina virtual de 32 bits

Cabeçalho de objeto de objeto comum de máquina virtual de 32 bits

|-----------------------------------------------------------|
|                    Object Header (64 bits)                |
|---------------------------------|-------------------------|
|             Mark Word (32 bits) | Klass Word (32 bits)    |
|---------------------------------|-------------------------|

Cabeçalho de objeto de objeto de array de máquina virtual de 32 bits

|---------------------------------------------------------------------------------|
|                                  Object Header (96 bits)                        |
|--------------------------------|-----------------------|------------------------|
|       Mark Word(32bits)        | Klass Word(32bits)    | array length(32bits)   |
|--------------------------------|-----------------------|------------------------|

Os detalhes do cabeçalho do objeto de máquina virtual de 32 bits são os seguintes

|-----------------------------------------------------------------------------------------------------------------|
|                                             Object Header(64bits)                                               |
|-----------------------------------------------------------------------------------------------------------------|
|                       Mark Word(32bits)                           |  Klass Word(32bits)    |      State         |
|-----------------------------------------------------------------------------------------------------------------|
|     hashcode:25                      | age:4 | biased_lock:0 | 01 | OOP to metadata object |      Nomal         |
|-----------------------------------------------------------------------------------------------------------------|
|     thread:23              | epoch:2 | age:4 | biased_lock:1 | 01 | OOP to metadata object |      Biased        |
|-----------------------------------------------------------------------------------------------------------------|
|     ptr_to_lock_record:30                                    | 00 | OOP to metadata object | Lightweight Locked |
|-----------------------------------------------------------------------------------------------------------------|
|     ptr_to_heavyweight_monitor:30                            | 10 | OOP to metadata object | Heavyweight Locked |
|-----------------------------------------------------------------------------------------------------------------|
|                                                              | 11 | OOP to metadata object |    Marked for GC   |
|-----------------------------------------------------------------------------------------------------------------|

Cabeçalho de objeto de máquina virtual de 64 bits

|-----------------------------------------------------------------------------------------------------------------|
|                                             Object Header(128bits)                                              |
|-----------------------------------------------------------------------------------------------------------------|
|                                   Mark Word(64bits)               |  Klass Word(64bits)    |      State         |
|-----------------------------------------------------------------------------------------------------------------|
|    unused:25|identity_hashcode:31|unused:1|age:4|biase_lock:0| 01 | OOP to metadata object |      Nomal         |
|-----------------------------------------------------------------------------------------------------------------|
|    thread:54|      epoch:2       |unused:1|age:4|biase_lock:1| 01 | OOP to metadata object |      Biased        |
|-----------------------------------------------------------------------------------------------------------------|
|                        ptr_to_lock_record:62                 | 00 | OOP to metadata object | Lightweight Locked |
|-----------------------------------------------------------------------------------------------------------------|
|                       ptr_to_heavyweight_monitor:62          | 10 | OOP to metadata object | Heavyweight Locked |
|-----------------------------------------------------------------------------------------------------------------|
|                                                              | 11 | OOP to metadata object |    Marked for GC   |
|-----------------------------------------------------------------------------------------------------------------|

lock : bit de sinalizador de status de bloqueio de 2 bits. Como queremos usar o mínimo de bits binários possível para representar o máximo de informações possível, o sinalizador de bloqueio é definido. O valor da marca é diferente, o significado de toda a palavra da marca é diferente.

enviesamento fechadura status
0 01 não feche
1 01 Bloqueio de polarização
0 00 Fechadura leve
0 10 Trava de peso pesado
0 11 Marca GC

bised_lock : se o objeto habilita o flag de bloqueio polarizado, que ocupa apenas 1 bit binário. Quando for 1, significa que o objeto possui um bloqueio polarizado; quando for 0, significa que o objeto não possui um bloqueio polarizado.
idade : idade do objeto Java de 4 dígitos. No GC, se o objeto for copiado uma vez na área do sobrevivente, a idade aumenta em 1. Quando o assunto atinge o limite definido, ele será promovido à velhice. Por padrão, o limite de idade para GC paralelo é 15 e o limite de idade para GC simultâneo é 6. Como a idade tem apenas 4 bits, o valor máximo é 15, por isso o -XX:MaxTenuringThresholdvalor máximo da opção é 15.
Identity_hashcode : código hash de identificação de objeto de 25 bits, usando tecnologia de carregamento lento. Chame o método de System.identityHashCode()cálculo e escreva o resultado no cabeçalho do objeto. Quando o objeto estiver bloqueado, o valor será movido para o monitor monitor.
thread : ID do thread segurando o bloqueio de polarização.
epoch : bias timestamp.
ptr_to_lock_record : Ponteiro para o registro de bloqueio na pilha.
ptr_to_heavyweight_monitor : Ponteiro para monitorar o monitor.

Como visualizar o cabeçalho do objeto

Para visualizar o cabeçalho do objeto, você precisa usar a ferramenta JOL.

<dependency>
     <groupId>org.openjdk.jol</groupId>
     <artifactId>jol-core</artifactId>
     <version>0.10</version>
</dependency>

import org.openjdk.jol.info.ClassLayout;
import org.openjdk.jol.vm.VM;
import static java.lang.System.out;

public class TestBiased {
    
    
    public static void main(String[] args) {
    
    
        Dog d= new Dog();
        //打印JVM的详细信息
        out.println(VM.current().details());
        //打印对应的对象头信息
        out.println(ClassLayout.parseInstance(a).toPrintable());
    }
}

class Dog {
    
    
}

A impressão é aproximadamente a seguinte.

21:46:08.204 c.TestBiased [main] - # Running 64-bit HotSpot VM.
# Objects are 8 bytes aligned.
# Field sizes by type: 8, 1, 1, 2, 2, 4, 4, 8, 8 [bytes]
# Array element sizes: 8, 1, 1, 2, 2, 4, 4, 8, 8 [bytes]

21:46:08.215 TestBiased [main] - cn.itcast.test.Dog object internals:
 OFFSET  SIZE   TYPE DESCRIPTION                               VALUE
      0     4        (object header)                           01 00 00 00 (00000001 00000000 00000000 00000000) (1)
      4     4        (object header)                           00 00 00 00 (00000000 00000000 00000000 00000000) (0)
      8     4        (object header)                           50 c8 e1 3f (01010000 11001000 11100001 00111111) (1071761488)
     12     4        (object header)                           71 01 00 00 (01110001 00000001 00000000 00000000) (369)
Instance size: 16 bytes
Space losses: 0 bytes internal + 0 bytes external = 0 bytes total

Se a impressão for diferente, você pode adicionar o parâmetro de opções VM -XX:-UseCompressedOopspara desativar a compactação do ponteiro.

Para entender o número de VALUE, você precisa entender o armazenamento de pouco endian

referência

memória-eficiente-java
compreensão aprofundada do cabeçalho do objeto Java marca palavra
Java objeto cabeçalho explicação detalhada da
entrevista de recrutamento da escola
Java estrutura do objeto Java e princípio de implementação de bloqueio e explicação detalhada MarkWord para
matar o entrevistador 1-sincronizado princípio subjacente (do cabeçalho do objeto Java à otimização de compilação instantânea)
Explore o armazenamento header-big-endian do objeto Java e o armazenamento little-endian

Acho que você gosta

Origin blog.csdn.net/e891377/article/details/108905401
Recomendado
Clasificación