2016-09-03 2 views
4

왜 개체 헤더가 64 비트 응용 프로그램에서 두 배 더 커 졌는지 이해할 수 없습니다. 개체 헤더가 8 바이트 였고 64 비트에서 16이라는 추가 바이트가 사용 되었습니까?64 비트 아키텍처에서 개체 헤더 크기가 두 배로 증가한 이유는 무엇입니까?

+0

https://codeblog.jonskeet.uk/2011/04/05/of-memory-and-strings/ –

+1

[.NET 객체의 메모리 오버 헤드 란 무엇입니까?] (http : //stackoverflow.com/questions/10655829/what-is-the-memory-overhead-of-a-net-object) –

답변

8

개체 헤더는 syncblk와 메서드 테이블 포인터 (일명 "유형 핸들")의 두 필드로 구성됩니다. 두 번째 필드는 이해하기 쉽습니다. 포인터이므로 이 64 비트 모드에서 4에서 8 바이트로 커야합니다.

syncblk은 플래그와 값 (잠금 소유자 스레드 ID, 해시 코드, 동기화 블록 색인)이 혼합 된 훨씬 덜 분명한 경우입니다. 64 비트 모드에서 더 크게 만들 이유는 없습니다. 중요한 것은 이후에 이후 GC가 개체를 수집하는 것입니다. 힙을 압축하여 여유 공간이 제거되지 않으면 오브젝트 공간이 여유 블록 목록에 참여합니다. 이중 연결 목록처럼 작동합니다. 두 번째 필드는 다음 빈 블록에 대한 정방향 포인터입니다. 객체 데이터 공간은 빈 블록의 크기를 저장하는 데 사용되며 객체가 12 바이트보다 작지 않은 기본적인 이유입니다. syncblk은 이전의 빈 블록에 백 포인터를 저장합니다. 이제는 포인터를 저장할만큼 커야하므로 8 바이트로 증가해야합니다. 따라서 8 + 8 = 16 바이트입니다.

Fwiw, 64 비트 모드의 최소 객체 크기는 24 바이트이지만 8 + 8 + 4 = 20 바이트는 모든 것이 8로 정렬되도록 보장합니다. 당신은 포인터 값을 L1 캐시 라인에 걸 치고 싶지 않을 것입니다. 약 3 배 느린 속도로 액세스합니다. <gcAllowVeryLargeObjects> 옵션은 나중에 추가되는 또 다른 이유입니다.

+0

고맙습니다. 대답은 매우 설명적입니다. –

관련 문제