2013-06-27 9 views
8

Chciałem wiedzieć, czy jest jakiś sposób, aby 64-bitowa maszyna wirtualna używała nagłówków obiektów 8-bajtowych zamiast 12-bajtowych nagłówków obiektów, jeśli używana pamięć RAM dla JVM ma 4 GB.Rozmiar nagłówka obiektu w języku Java na maszynie wirtualnej 64-bitowej z <4 GB pamięci RAM

A może jest tak w systemie Linux, jeśli nie w Windows? Czy ktoś mógłby przetestować to za pomocą tego kodu?

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."); 
    } 
} 

Odpowiedz

16

Wygląda na to, że nie ma możliwego 8-bajtowego nagłówka obiektu na 64-bitowej maszynie JVM. Nagłówek składa się ze "słowa znacznika", wskaźnika do klasy obiektu, rozmiaru tablicy w przypadku tablicy i dopełnienia, aby osiągnąć następną ośmiobajtową granicę.

,------------------+------------------+------------------ +---------------. 
    | mark word  | klass pointer | array size (opt) | padding | 
    `------------------+------------------+-------------------+---------------' 
  • słowny znak towarowy może być używany do przechowywania rodzime wskaźniki to implement locks and to help GC, więc zajmuje 8 bajtów na 64-bitowym JVM.
  • Przy stosach mniejszych niż 32 GB wskaźnik do klasy obiektu is compressed to 4 bytes.
  • Wypełnienie może służyć do przechowywania jednego z pól.

Dlatego nagłówek obiektu w systemie 64-bitowym może zajmować zaledwie 8 + 4 = 12 bajtów, ale nie mniej.

3

Dla 64-bitowych maszyn wirtualnych są opcje:

  1. pomocą sprężonego wskazówek poprzez -XX: + UseCompressedOops (domyślnie włączone na Java 6)

W tym przypadku: nagłówki obiekt zostanie 12 bajtów, nagłówki tablica będzie 16 bajtów (ostatnie cztery bajty dla rozmiaru tablicy)

2.Nie wykorzystując skompresowane wskazówek poprzez -xx: -UseCompressedOops

W takim przypadku: nagłówki obiektów będą miały 16 bajtów, nagłówki tablic będą miały 20 bajtów (ostatni 4 bajty dla rozmiaru tablicy).

Podany powyżej kod nie jest niezależny od rozmiaru VM i da różne wyniki dla 32- bitowy i 64-bitowy vms. Musisz wziąć pod uwagę bitowe i skompresowane czynniki, aby obliczyć prawidłowy rozmiar.

-1

pomocą sprężonego wskazówek poprzez -XX: + UseCompressedOops (domyślnie włączone na Java 6)

nie jest to prawdą dla wszystkich wersji Java 6. -XX:+UseCompressedOops jest domyślnie włączona zaczynając Java 6u25

+0

Odwołując się do odpowiedzi @NitinS, możesz używać komentarzy zamiast publikować odpowiedzi. –

Powiązane problemy