Java프로그래밍시니어 자바 개발자

**HotSpot JVM**은 **Object.hashCode()**가 가비지 수집기가 객체를 다른 힙 주소로 이동한 후에도 일관된 값을 반환하도록 어떻게 보장합니까? 그럼에도 불구하고 아이덴티티 해시는 원래 메모리 위치에서 파생됩니다.

Hintsage AI 어시스턴트로 면접 통과

질문에 대한 답변.

HotSpot JVM은 가비지 수집주기가 객체를 이동하기 전에 초기 메모리 주소에서 해시 코드를 계산하고 이를 객체 헤더의 마크 워드에 캐시하여 **Object.hashCode()**의 일관성을 보장합니다. 이 마크 워드에는 해시 코드 필드와 해시가 물리화되었음을 나타내는 비트 플래그가 포함되어 있어 이후 호출 시 캐시된 값을 검색하고 재계산하지 않습니다. 따라서 G1이나 ZGC와 같은 수집기가 객체를 새 주소로 이동하더라도 아이덴티티 해시는 물리적 포인터와 분리되어 불변 헤더 메타데이터에 저장되기 때문에 안정적으로 유지됩니다.

생활에서의 상황

분산 웹 애플리케이션은 IdentityHashMap을 사용하여 여러 애플리케이션 노드에서 활성 Session 객체를 추적하고 부하 분산 작업 중 캐시 친화 라우팅을 위해 **System.identityHashCode()**에 의존했습니다. 트래픽이 최고조에 달했을 때, ZGC 저지연 수집기는 젊은 세대 객체의 빈번한 동시 이동을 수행하여 짧은 정지 시간을 유지했습니다. 이동 시 아이덴티티 해시가 변경되었더라면 세션 친화성이 깨져 요청이 노드 간에 흘러넘치고 일관성 보장에 위배될 수 있었습니다.

한 가지 접근법은 각 Session을 생성할 때 UUID 인스턴스를 생성하고 별도의 **ConcurrentHashMap<UUID, Session>**을 유지하는 것이었습니다. 장점: JVM 객체 수명 및 이동 메커니즘으로부터 완전한 독립성. 단점: 세션 객체마다 16바이트의 추가 오버헤드가 발생하고 UUID 생성을 통한 할당 압박이 발생하여 피크 트래픽 동안 할당 속도를 포화시킬 수 있습니다.

팀은 JNI 중요 참조를 사용하여 세션 객체를 메모리에 고정하여 GC 이동을 방지하는 것을 고려했습니다. 장점: 안정적인 메모리 주소와 따라서 안정적인 아이덴티티 해시를 보장합니다. 단점: ZGC에서 전체 힙 영역을 고정하여 파편화를 초래하고 수집기의 동시 이동 기능을 무력화하여 꺼림칙한 정지 시간을 유발합니다.

선택한 솔루션은 아이덴티티 해시 코드가 일정하다는 JVM 명세 보장을 활용하고 HotSpot의 마크 워드 캐싱 구현을 결합했습니다. 장점: 추가 메모리 오버헤드가 없고, 할당 비용이 없으며, ZGC와 같은 공격적인 수집기와의 완전한 호환성을 가집니다. 단점: 명세에 명시된 대로 JVM 구현 세부정보에 대한 신뢰가 필요합니다.

애플리케이션은 핀이나 보조 식별자 없이 수백만 개의 ZGC 사이클 동안 완벽한 세션 친화성을 유지하며 서브 밀리초 정지 시간을 달성하고 IdentityHashMap의 무결성을 유지했습니다.

후보자들이 자주 놓치는 점

Does System.identityHashCode() always return the object's current memory address as an integer?

아니요. 초기 계산이 엔트로피로서 메모리 주소를 사용할 수 있지만, 결과는 즉시 객체 헤더에 저장되고 그 이후에는 변경되지 않습니다. 이는 반환된 정수가 GC 이동 후 객체의 현재 위치를 반영하지 않음을 의미하며, 개발자는 이를 포인터나 메모리 주소 프로브로 취급해서는 안 됩니다.

Can the identity hash code be negative, and how do collections handle this?

예, 유효한 삼십이 비트 정수 값은 모두 가능하며, 음수도 포함됩니다. IdentityHashMap(h ^ (h >>> 16)) & (length-1)와 같은 마스킹 작업을 통해 음수 해시를 처리하며, Integer.MIN_VALUE에서 두의 보수 오버플로우로 실패하는 **Math.abs()**는 피합니다.

Is the identity hash code guaranteed to be unique across all objects?

아니요. 삼십이 비트 정수 공간은 잠재적인 힙 주소 공간보다 작기 때문에 충돌이 발생할 수 있습니다. HotSpot은 Marsaglia의 xor-shift 방식 또는 주소 기반 해시를 사용하여 값을 잘 분배하지만, 고유성은 보장되지 않으며, IdentityHashMap은 단순히 해시 코드가 아닌 참조 평등성을 사용하여 식별합니다.