O artigo leva você entender o quanto de memória você escreve objetos Java realmente representou?

página blog pessoal de navegação (clique à direita ligação para abrir um blog pessoal): Daniel levá-lo em tecnologia de pilha 

Java objeto cabeçalho modelo de memória

Vamos dar uma olhada em um objeto de modelo de memória Java é tipo de como? Desde a nossa máquina virtual é dividido em 32-bit e 64-bit, é certamente o seu modelo é diferente, eu listei abaixo na coluna de 32-bit e 64-bit máquina virtual máquina virtual Javamodelo de memória objeto cabeçalho. # 32

# 64

compressão apontador de 64 bits

Porque o autor do ambiente local jdk1.8, 64-bit máquina virtual, eu estou aqui para 64 máquinas virtuais (compressão ponteiro aberta) para analisar, porque, por padrão, jdk1.8 o 64-bit de compressão de máquina virtual é ativado por ponteiro padrão.

Java cabeçalho objecto consiste em duas partes, a primeira parte é  Mark Word, esta é a  Java realização de bloqueio do princípio de uma parte importante da outra parte  Klass Word.

Klass Palavra  aqui é realmente uma máquina virtual projetado oop-klass modelmodelo, aqui OOPrefere-se à Ordinary Object Pointer(ponteiro objeto comum), parece um ponteiro é realmente escondido no ponteiro no objeto. klass ele contém metadados e métodos, para descrever a  Java classe. espaço aberto sob seus 32bits ocupação ponteiros compressão em ambiente de máquina virtual de 64 bits.

Mark Palavra  é o foco de nossa análise, este conhecimento será projetado para bloquear. Mark Word 64bits ocupar espaço no ambiente da máquina virtual 64 bits. O toda Mark Worda alocação Há várias situações:

  1. Desbloqueado (normal):  código de hash ( identity_hashcode) ocupa 31bits, idade gerações ( age) ocupa 4 bits, o modo de polarização ( biased_lock) ocupa 1 bit, uma bandeira de bloqueio ( lock) ocupa 2 bits, 26bits restantes não utilizadas (isto é, todos os 0)
  2. Pode ser tendencioso (inclinada):  ID de segmento representaram 54bits, epoch respondendo por 2 bits, idade gerações ( age) ocupa 4 bits, o modo tendencioso (biased_lock) ocupa 1 bit, uma bandeira de bloqueio (lock) ocupa de 2 bits, o 1bit restante não utilizada.
  3. travamento leve (Lightweight fechado) : um ponteiro trinco ocupa 62bits, a bandeira de bloqueio ( lock) ocupa 2 bits.
  4. fechaduras pesos pesados (bloqueado pesado) : um ponteiro trinco ocupa 62bits, bandeira de bloqueio ( lock) ocupa 2 bits.
  5. marca GC : bandeira representaram 2bits, o resto está vazia (isto é, enchendo 0)

Estes são nossa determinação de modelo de memória cabeçalho objeto Java, enquanto objeto Java, em seguida, ele certamente vai incluir cabeçalho objeto, o que significa que esta parte do consumo de memória é inevitável. Sob Então, na minha máquina virtual de 64 bits, Jdk1.8 (aberto de compressão ponteiro) meio ambiente, qualquer objeto, o que não fazer, desde que a declaração de uma classe, então o seu consumo de memória em, pelo menos, 96bits, que é pelo menos 12 bytes.

verificação Modelo

Vamos olhar algum código para validar o modelo de memória acima, recomendado aqui OpenJDK da ferramenta Jol , ele pode ajudá-lo a ver a memória alvo de ocupação.

Primeiro adicione maven dependente

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

Vamos dar uma olhada, só para criar uma classe comum, o que atributos não adicionar, quanto espaço é ocupado?

/**
 * @description:
 * @author: luozhou
 * @create: 2020-02-26 10:00
 **/
public class NullObject {

}

De acordo com a nossa análise Java modelo de memória objeto anterior, um objeto vazio, é apenas uma cabeça de assunto, sob a compressão ponteiro condição vai levar até 96 bits, que é 12byte.

Executar ferramenta para vista espaço ocupado

 public static void main(String[] args) {
        System.out.println(ClassLayout.parseInstance(new NullObject()).toPrintable());
    }

A linha acima de código analisa NullObject você criar um novo destino, a quantidade de memória. Nós olhamos como a implementação dos resultados: consumo de memória

Aqui encontramos os resultados mostram: Instance size:16 byteso resultado é de 16 bytes, a nossa previsão anterior de 12 bytes não são os mesmos, por que isso acontece? Nós vemos a figura acima, existem três linhas de cabeçalho objeto, cada um ocupando 4 bytes, então a cabeça é de 12 bytes, e isso é consistente com nossos cálculos, a última linha é uma máquina virtual cheio de 4 bytes, então porque virtual preenchimento confidenciais quatro bytes dele?

Alinhamento de memória

Quer saber por que a máquina virtual está cheio de 4 bytes, precisamos entender o que é o alinhamento de memória?

Nós olhamos memória do programador é esta:

A figura mostra uma forma de realização de uma memória de leitura poço rabanete. Mas, na verdade a CPU não ir com uma leitura de memória um byte e escrever. Ao invés, a memória é um CPU lê um tamanho de bloco de leitura e similares pode ser 2,4,6,8,16 tamanho em bytes. Nós chamamos este tamanho do bloco granularidade acesso à memória. FIG segue:

Suponha CPU de um plataforma de 32 bits, em seguida, ele vai para um tamanho de partícula de 4 bytes ler bloco de memória. Por que precisamos de memória align? Há duas razões principais:

  • Platform (portabilidade) razões: Nem todas as plataformas de hardware são capazes de acessar quaisquer dados em qualquer endereço. Por exemplo: uma plataforma de hardware específica só permite obter tipos específicos de dados em um endereço específico, caso contrário ele irá levar a uma situação anormal.
  • Por motivos de desempenho: Se um acesso à memória unaligned irá resultar em duas vezes o acesso à memória CPU, e ter ciclos de clock adicionais para o alinhamento e operação do processo. E alinhou-se requer apenas um acesso à memória para concluir a operação de leitura.

Eu usei a legenda para explicar o processo da CPU para a memória de acesso não-alinhados:

Na figura, assumindo uma leitura CPU é de 4 bytes, 8 bytes neste espaço de memória contínua, se os meus dados não estiver alinhado, o endereço armazenado nos blocos de memória 1,2,3,4, e que lê o CPU vai exigir dois para ler, além de operações computacionais adicionais:

  1. CPU primeiro lê o primeiro bloco de endereço de memória desalinhado, lê o byte 0-3. E remover os bytes 0.
  2. CPU lê o endereço de memória desalinhado do segundo bloco de novo, 4-7 bytes ler. 5,6,7 e remover os bytes de byte.
  3. Os combinados 1-4 bytes de dados.
  4. Fundidas em registo.

Portanto, nenhum alinhamento de memória fará com CPU adicional operação de leitura, e requer cálculo adicional. Se você fizer um alinhamento de memória, CPU pode começar a ler directamente a partir do endereço 0, uma vez que os dados que você quer ler, não houve operações de leitura adicionais e operações aritméticas, economiza o tempo de execução. Nós usamos o espaço para o tempo, o que é por isso que precisamos estar alinhados memória.

Voltar vazio Java objectos cheios com quatro bytes do problema, porque o cabeçalho de bites originais é de 12 bytes, máquinas de 64-bit, o alinhamento da palavra de memória é de 128, que é de 16 bytes, por isso, também precisa encher quatro palavras seção.

cálculo consumo de memória não-nula de objeto

Sabemos que um objeto vazio é ocupar 16 bytes, um objeto não nulo exatamente quantos bytes ocupados isso? Nós ainda escrever sob uma categoria geral para verificar:

public class TestNotNull {
    private NullObject nullObject=new NullObject();
    private int a;
}

Esta classe de demonstração introduziu outros objetos, sabemos que into tipo é de 4 bytes, NullObjecto objeto ocupa 16 bytes, objeto cabeçalho é responsável por 12 bytes, há um caso muito importante  NullObjecté uma referência na classe atual, portanto, objeto real não existe, mas apenas manter o endereço de referência , o endereço de referência ocupa 4 bytes, o total é de 12 + 4 + 4 = 20 bytes, o alinhamento de memória é de 24 bytes. Não estamos debaixo para verificar este resultado:

public static void main(String[] args) {
        //打印实例的内存布局
        System.out.println(ClassLayout.parseInstance(new TestNotNull()).toPrintable());
        //打印对象的所有相关内存占用
        System.out.println(GraphLayout.parseInstance(new TestNotNull()).toPrintable());
        //打印对象的所有内存结果并统计
         System.out.println(GraphLayout.parseInstance(new TestNotNull()).toFootprint());
    }

Os resultados são os seguintes:

Podemos ver TestNotNulla classe espaço é de 24 bytes, que ocupa 12 bytes de cabeçalho, a variável aé intdo tipo ocupam 4 bytes, a variável nullObjecté referenciado, leva-se 4 bytes, e finalmente preenchido com quatro bytes, para um total de 24 bytes, consistentes com a nossa previsão anterior. No entanto, porque nós instanciar NullObjecteste objeto na memória para um tempo, então precisamos adicionar 16 bytes de espaço de memória do objeto, ou seja um total de 24bytes + 16bytes = 40 bytes. Os resultados finais da nossa impressão estatística o número é de 40 bytes, por isso a nossa análise está correta.

Esta é também a forma de analisar o quanto de memória a idéia de um objeto real é ocupado, de acordo com esta linha de pensamento mais openJDK da ferramenta jol basicamente pode escrever sua própria compreensão do "objeto" Pródigo-lhe exatamente o quanto de memória.

resumo

Este artigo se concentra em como me analisar a quantidade de espaço de memória está realmente ocupado por um objeto Java, os pontos principais são resumidas como segue:

  1. modelo de objeto Java na memória de cabeça 32 máquinas virtuais e máquinas virtuais de 64 bits não é a mesma, de 64 bits máquina virtual é dividido em modelo de cabeça aberta e não aberta ponteiro ponteiro de compressão de compressão de dois tipos de objetos, de modo que um total de três tipos de objetos cabeça modelo .
  2. alinhamento de memória é principalmente por causa de razões de desempenho e plataformas, este artigo é para motivos de desempenho determinação.
  3. objeto cálculo da pegada de memória vazio Para calcular a memória alinhamento atenção, memória, cálculo de uma referência de objeto não nulo mais o espaço atenção e pegada ocupada pela instância objeto original.

aprendizagem anexado Java / C / C ++ / máquina / Algoritmos e Estruturas de Dados / front-end / Android / Python / programador de leitura / únicos livros livros Daquan:

(Clique no direito de abrir lá no blog pessoal seco): seca Técnico Floração
===== >> ① [Java Daniel levá-lo no caminho para a avançada] << ====
===== >> ② [+ acm algoritmo de estrutura de dados Daniel levá-lo no caminho para a avançada] << ===
===== >> ③ [banco de dados Daniel levá-lo no caminho para a avançada] << == ===
===== >> ④ [front-end Daniel web para levá-lo no caminho para a avançada] << ====
===== >> ⑤ [machine python aprendizagem e Daniel levá-lo entrada para o estrada avançada] << ====
===== >> ⑥ [arquiteto Daniel levá-lo no caminho para a avançada] << =====
===== >> ⑦ [C ++ Daniel avançou para levá-lo na estrada] << ====
===== >> ⑧ [ios Daniel levá-lo no caminho para a avançada] << ====
=====> > ⑨ [segurança web Daniel levá-lo no caminho para a avançada] << =====
===== >> ⑩ [sistema operacional Linux e Daniel levá-lo no caminho para a avançada] << = ====

Não há frutas não ganhos, espero que você jovens amigos, amigos querem aprender técnicas, superando todos os obstáculos no caminho da estrada determinado a amarrar em tecnologia, entender o livro, e em seguida, bater no código, entender o princípio, e ir prática, vai ele vai lhe trazer a vida, seu trabalho, seu futuro um sonho.

Publicado 47 artigos originais · ganhou elogios 0 · Visualizações 268

Acho que você gosta

Origin blog.csdn.net/weixin_41663412/article/details/104892981
Recomendado
Clasificación