나는 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은 이것이 객체에 표시된 해시 코드가 아니라 편향된 잠금임을 어떻게 알 수 있습니까? 나는 또한 궁금합니다 : 신기원 비트가 나타내는 것은 무엇입니까?