O exemplo neste artigo descreve como calcular (ou estimar) a quantidade de memória ocupada por um objeto Java. Compartilhe com todos para sua referência. A análise específica é a seguinte:
Normalmente falamos sobre o uso de memória heap no contexto de "casos gerais". As duas situações a seguir não estão incluídas:
Em alguns casos, a JVM não coloca o objeto no heap. Por exemplo: Em princípio, um pequeno objeto local de thread existe na pilha, não no heap.
A quantidade de memória ocupada por um Objeto depende do estado atual do Objeto. Por exemplo: se o bloqueio de sincronização do Objeto está em vigor ou se o Objeto está sendo reciclado.
Vamos primeiro dar uma olhada na aparência de um único objeto na pilha.
No heap, cada objeto é composto por quatro campos (A, B, C e D). Vamos explicar cada um a seguir:
R: Cabeçalho do objeto, que ocupa poucos bytes e expressa informações sobre o status atual do objeto.
B: O espaço ocupado pelos campos do tipo básico (os campos nativos referem-se a int, boolean, short, etc.)
C: O espaço ocupado pelos campos do tipo de referência (os campos do tipo de referência referem-se a referências a outros objetos, cada referência ocupa 4 bytes)
D: Espaço ocupado pelo filler (o que é filler será explicado mais adiante)
Abaixo explicamos A, B, C e D um por um
A: Cabeçalho do objeto
Na memória, o espaço total ocupado por cada objeto não inclui apenas o espaço necessário para variáveis declaradas dentro do objeto, mas também inclui algumas informações adicionais, como cabeçalhos e preenchimentos de objetos. A função do "cabeçalho do objeto" é registrar o nome da instância, o ID e o status da instância de um objeto (por exemplo, se a instância atual está "acessível" ou o status do bloqueio atual, etc.).
Na versão atual da JVM (Hotspot), o número de bytes ocupados pelo "cabeçalho do objeto" é o seguinte:
Um objeto comum, ocupando 8 bytes
Matriz, ocupa 12 bytes, incluindo 8 bytes + 4 bytes de objetos comuns (comprimento da matriz)
B: tipo básico
boolean e byte ocupam 1 byte, char e short ocupam 2 bytes, int e float ocupam 4 bytes, long e double ocupam 8 bytes
C: tipo de referência
Cada tipo de referência ocupa 4 bytes
D: enchimento
No Hotspot, o espaço total ocupado por cada objeto é calculado como um múltiplo de 8. Quando o espaço total ocupado pelo objeto (cabeçalho do objeto + variáveis declaradas) for menor que um múltiplo de 8, ele será preenchido automaticamente. Entretanto, esses espaços preenchidos podem ser chamados de “preenchimentos”. Vejamos um exemplo específico:
Um objeto vazio (sem nenhuma variável declarada) ocupa 8 bytes -> o cabeçalho do objeto ocupa 8 bytes
Uma classe que declara apenas uma variável de tipo booleano ocupa 16 bytes -> cabeçalho do objeto (8 bytes) + booleano (1 bytes) + preenchimento (7 bytes)
Uma classe que declara 8 variáveis de tipo booleano ocupa 16 bytes -> cabeçalho do objeto (8 bytes) + booleano (1 bytes) * 8
Os exemplos acima nos ajudarão a aprofundar nossa compreensão da programação Java.