Tamanho do header do object em Java na VM de 64 bits com <4 GB de RAM

Eu queria saber se há alguma maneira de fazer com que a VM de 64 bits use headers de object de 8 bytes em vez de headers de object de 12 bytes se a RAM utilizável da JVM for de 4 GB de qualquer maneira.

Ou é assim no Linux, se não no Windows? Alguém poderia testar isso com esse código?

import java.lang.reflect.Field; import sun.misc.Unsafe; public class ObjectSizes { String s1; String s2; public static void main(String[] args) throws Exception { Unsafe unsafe; try { Field field = Unsafe.class.getDeclaredField("theUnsafe"); field.setAccessible(true); unsafe = (Unsafe)field.get(null); } catch (Exception ex) { throw new RuntimeException("Can't get Unsafe instance.", ex); } Field s1Field = ObjectSizes.class.getDeclaredField("s1"); Field s2Field = ObjectSizes.class.getDeclaredField("s2"); long s1OffSet = unsafe.objectFieldOffset(s1Field); long s2OffSet = unsafe.objectFieldOffset(s2Field); System.out.println("We are running "+System.getProperty("java.version")); System.out.println("Object header size is "+s1OffSet+" bytes."); System.out.println("Object reference size is "+(s2OffSet-s1OffSet)+" bytes."); } } 

Não parece possível ter um header de object de 8 bytes em uma JVM de 64 bits. O header consiste em uma “palavra de marca”, um ponteiro para a class do object, tamanho da matriz no caso de uma matriz e preenchimento para atingir o próximo limite de 8 bytes.

  ,------------------+------------------+------------------ +---------------. | mark word | klass pointer | array size (opt) | padding | `------------------+------------------+-------------------+---------------' 
  • A palavra de marca pode ser usada para armazenar pointers nativos para implementar bloqueios e para ajudar o GC , por isso ocupa 8 bytes em uma JVM de 64 bits.
  • Com heaps menores que 32 GB, o ponteiro para a class do object é compactado em 4 bytes .
  • O preenchimento pode ser usado para armazenar um dos campos.

Portanto, o header do object em um sistema de 64 bits pode ocupar tão pouco quanto 8 + 4 = 12 bytes, mas não menos.

Para VMs de 64 bits, existem opções:

  1. Usando pointers compactados via -XX: + UseCompressedOops (ativado por padrão no Java 6)

Nesse caso: os headers de objects terão 12 bytes, os headers de matriz serão 16 bytes (os últimos 4 bytes para o tamanho da matriz)

2.Não usando pointers compactados via -XX: -UseCompressedOops

Nesse caso: headers de objects terão 16 bytes, headers de matriz serão 20 bytes (últimos 4 bytes para tamanho de matriz)

O código fornecido acima não é independente de tamanho de bit de VM e fornecerá resultados diferentes para vms de 32 e 64 bits. Você precisa considerar os fatores O-Bess e Oops comprimidos para calcular o tamanho correto.

Usando pointers compactados via -XX: + UseCompressedOops (ativado por padrão no Java 6)

Isso não é verdadeiro para todas as versões do Java 6. -XX:+UseCompressedOops é ativado por padrão, começando com o Java 6u25

Intereting Posts