Java로 객체 / 배열을 할당 할 때 오버 헤드가 발생하는 이유는 무엇입니까?


9

Java에서 배열이 차지하는 바이트 수는 얼마입니까? 64 비트 시스템이라고 가정하고 배열에 N 개의 요소가 있다고 가정하므로 이러한 모든 요소는 다른 유형의 배열에 대해 2 * N, 4 * N 또는 8 * N 바이트를 차지합니다.

Coursera의 강의에 따르면 N 요소 배열의 경우 2 * N + 24, 4 * N + 24 또는 8 * N + 24 바이트를 차지하고 24 바이트는 오버 헤드라고하지만 오버 헤드가 왜되는지 설명하지 못했습니다 필요합니다.

또한 개체에는 16 바이트 인 오버 헤드가 있습니다.

이 오버 헤드는 정확히 무엇입니까? 이 24/16 바이트는 무엇으로 구성되어 있습니까?

또한 이러한 오버 헤드가 Java에만 존재합니까? C, C ++ 및 Python은 어떻습니까?



1
@Gnijuohz :이 오버 헤드는 어떤 데이터로 구성되어 있습니까?
FrustratedWithFormsDesigner 4

@ YannisRizos : OP는 배열에 대해 실제로 24 바이트에 무엇이 있는지 알고 싶어합니다.
FrustratedWithFormsDesigner 4

@FrustratedWithFormsDesigner Ah, 그것은 내 것보다 질문에 대한 더 나은 해석 인 것 같습니다.
yannis

@YannisRizos 내 나쁜 태도에 대해 죄송합니다. 그러나 그 링크를 게시하면 도움이 될 수 없지만 일종의 풍자라고 생각합니다. 너무 방어 적입니다.
Gnijuohz

답변:


16

각 Java 오브젝트에는 JVM에 중요한 정보가 포함 된 헤더가 있습니다. 가장 중요한 것은 객체의 클래스 (한 기계어)에 대한 참조이며 가비지 수집기에서 사용하는 플래그가 있으며 (모든 객체를 동기화 할 수 있기 때문에) 다른 기계어를 차지하는 동기화를 관리하기 위해 (부분 단어를 사용하여 성능이 나쁘다). 32 비트 시스템에서는 8 바이트, 64 비트에서는 16 바이트 인 2 워드입니다. 배열에는 배열 길이에 대한 int 필드가 추가로 필요합니다. 이는 또 다른 4 바이트이며 64 비트 시스템에서는 8 일 수 있습니다.

다른 언어들에 관해서는 :

  • C에는 객체가 없으므로 물론 객체 헤더가 없지만 별도로 할당 된 각 메모리 조각에 헤더가있을 수 있습니다.

  • C ++에서는 가비지 수집이없고 동기화에 임의의 객체를 사용할 수 없지만 재정의 된 메소드가있는 클래스가있는 경우 각 객체는 해당 객체에 대한 Java 객체의 참조와 같이 vtable에 대한 포인터를 갖습니다. 가비지 수집을 수행하는 스마트 포인터를 사용하는 경우 하우스 키핑 데이터가 필요합니다.

  • 파이썬에 대해서는 잘 모르지만 클래스에 대한 참조와 가비지 수집기에 대한 하우스 키핑 정보가 필요하다고 확신합니다.


:-) 객체 헤더, 작지만 중요한 단계의 크기를 줄이기 위해 순간에 오픈 JDK에서 일어나는 일이있다
마티 Verburg을

C ++에서는 다형성 클래스에만 vtable이 필요합니다. std::pair<int, float>vtable이 전혀 필요없는 간단한 클래스입니다. 결과적으로 8 바이트로 잘 맞을 수 있습니다. 또한 스마트 포인터는 실제로 하우스 키핑을 추가 할 필요가 없습니다. 명확한 반례는입니다 std::unique_ptr<T>. 이는 일반적으로 raw만큼이나 큽니다 T*(unique_ptr은 GC를 수행하지 않습니다).
MSalters

4
C는 또한 오버 헤드가 있으며, 할당 된 각 malloc메모리 블록에는 헤더가 필요 free합니다.
herby

내가 아는 적어도 하나의 malloc 라이브러리는 32 비트 시스템에서 8 바이트 헤더를 사용합니다 (2 바이트 센티넬 값 2 세트, IIRC로 묶인 4 바이트 길이).
Donal Fellows
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.