2014-12-09 2 views
0

나는 64 비트 HotSpot VM (v8)에서 Java object layout의 출력을 이해하려고 노력하고있다. 나는 first three bit of the mark word이 연결된 클래스 파일의 해설에 따라 날씨가 바이어스 된 잠금 또는 바이어스되지 않은 잠금이 인스턴스에 설정되어 있어야한다고 설명하는 방법을 이해하지 못합니다. 나는 다음과 같은 출력을 얻을인스턴스의 표시 단어를 해석하는 방법은 무엇입니까?

ClassLayout layout = ClassLayout.parseClass(Object.class); 
Object object = new Object(); 
System.out.println(layout.toPrintable(object)); 

에 의해 JOL를 사용 Object의 인스턴스를 분석 할 때

는 : HotSpot's description of the mark word (처음 8 바이트)에서

java.lang.Object object internals: 
OFFSET SIZE TYPE DESCRIPTION     VALUE 
     0  4  (object header)    01 00 00 00 (0000 0001 0000 0000 0000 0000 0000 0000) 
     4  4  (object header)    00 00 00 00 (0000 0000 0000 0000 0000 0000 0000 0000) 
     8  4  (object header)    e5 01 00 f8 (1110 0101 0000 0001 0000 0000 1111 1000) 
    12  4  (loss due to the next object alignment) 
Instance size: 16 bytes (estimated, add this JAR via -javaagent: to get accurate result) 
Space losses: 0 bytes internal + 4 bytes external = 4 bytes total 

을, 나는이 해석해야한다고 이해 출력의 비트 범위 위에 다음과 같습니다.

  • 00:01 - 잠금 신고
  • 02:02 (예 00.) - 깃발 바이어스 잠금
  • 03:06 (예 0.) - 젊은 가비지 컬렉션 반복의 수와 같은 나이. (예 : 0000)
  • 07:07 - 사용하지 않습니다. (항상 1 인 것처럼 보입니다.)
  • 08:39 - Identity 해시 코드. (계산 후에 만 ​​0으로 채워집니다.)
  • 40:63 - 사용하지 않습니다. (제로로 충전 될 것으로 보인다.)

해시 코드 범위

적어도 해시 코드에 대한 레이아웃의 확인이 용이하게 식별 해시 코드를 계산하고 비교함으로써 확인 될 수있다 값 : 해시 코드 (리마인더가 0으로 설정 될 때 단지 31 비트 대신에 32로 표시되어 있다는 사실을 무시하는) 실제 비트로서 설정된다

ClassLayout layout = ClassLayout.parseClass(Object.class); 
Object object = new Object(); 
// Check that the hash code is not set. 
System.out.println(layout.toPrintable(object)); 

System.out.println("hash code: 0x" + Integer.toHexString(object.hashCode())); 
// Confirm that the value is set: 
System.out.println(layout.toPrintable(object)); 

// Compute the hash code manually: 
Field field = Unsafe.class.getDeclaredField("theUnsafe"); 
field.setAccessible(true); 
Unsafe unsafe = (Unsafe) field.get(null); 
long hashCode = 0; 
for (long index = 7; index > 0; index--) { 
    hashCode |= (unsafe.getByte(object, index) & 0xFF) << ((index - 1) * 8); 
} 
System.out.println("hash code: 0x" + Long.toHexString(hashCode)); 

. 잠금에 대한 플래그는 모두 예상대로 0으로 설정됩니다.

바이어스

markOops 잠금의 레이아웃 검증은 또한 개체가 편향된 로킹을받을 때의 레이아웃을 제공한다.

  • 08:09이 바이어스 잠금을 보유하는 스레드의 포인터 - - 신기원은
  • 10:63
  • 비트 : 여기, 마지막 두 개의 글 머리 기호는 다음과 같은 범위로 대체됩니다.

-XX:BiasedLockingStartupDelay=0으로 다음 코드를 실행하는 바이어스 된 잠금을 시도 할 때 편향 잠금이 설정되는 방식을 관찰 할 수 있습니다.나는 다음과 같은 코드를 실행하면 :

ClassLayout layout = ClassLayout.parseClass(Object.class); 
Object object = new Object(); 

// Before using any lock, the layout is as above. 
System.out.println(layout.toPrintable(object)); 

// When acquiring the lock, the thread ID can be seen as below: 
synchronized (object) { 
    System.out.println(layout.toPrintable(object)); 
} 

// After leaving the lock, the object is biased towards this thread: 
System.out.println(layout.toPrintable(object)); 

아래와 같이 바이어스 잠금 초기 잠금 후 마크 단어에서 볼 수 있습니다 :

java.lang.Object object internals: 
OFFSET SIZE TYPE DESCRIPTION     VALUE 
     0  4  (object header)    05 f0 3f 02 (0000 0101 1111 0000 0011 1111 0000 0010) 
     4  4  (object header)    00 00 00 00 (0000 0000 0000 0000 0000 0000 0000 0000) 
     8  4  (object header)    e5 01 00 f8 (1110 0101 0000 0001 0000 0000 1111 1000) 
    12  4  (loss due to the next object alignment) 
Instance size: 16 bytes (estimated, add this JAR via -javaagent: to get accurate result) 
Space losses: 0 bytes internal + 4 bytes external = 4 bytes total 

나는이 같은 해시 코드를 나타내는되지 않는다는 것을 확인할 수 있습니다 object.hashCode()을 호출하면 마크 단어가 바뀝니다 (편향된 잠금이 취소됨).

바이어스 된 잠금 및 비 바이어스 된 잠금에 대한 플래그가 여전히 0으로 설정되어 있다는 것이 이해가되지 않습니다. HotSpot은 이것이 객체에 표시된 해시 코드가 아니라 편향된 잠금임을 어떻게 알 수 있습니까? 나는 또한 궁금합니다 : 신기원 비트가 나타내는 것은 무엇입니까?

답변

1

대답은 간단합니다. OpenJDK의 주석이 오래되었으며 마크 단어가 오늘 다른 구조로되어 있습니다.

관련 문제