Чому накладні витрати при розподілі об’єктів / масивів на Java?


9

Скільки байтів займає масив у Java? Припустимо, це 64-бітова машина, а також припустимо, що в масиві є N елементів, тому всі ці елементи займуть 2 * N, 4 * N або 8 * N байт для різних типів масиву.

І лекція в Coursera говорить, що вона буде займати 2 * N + 24, 4 * N + 24 або 8 * N + 24 байт для масиву N елементів і 24 байти називається накладними, але не пояснила, чому накладні витрати потрібні.

Також об'єкти мають накладні витрати, що становить 16 байт.

Які саме ці накладні витрати? З чого складаються ці 24/16 байти?

Крім того, чи існують ці накладні витрати лише на Java? Як щодо C, C ++ та Python?


2
Ознайомтесь: stackoverflow.com/a/258150/1029272
Деко

1
@Gnijuohz: Ви хочете запитати: з яких даних складається цей наклад?
FrustratedWithFormsDesigner

@YannisRizos: Я думаю, що ОП хоче знати, що є насправді в цих 24 байтах, для масивів.
FrustratedWithFormsDesigner

@FrustratedWithFormsDesigner Ага, це, здається, краще тлумачення питання, ніж моє.
янніс

@YannisRizos вибачте за моє погане ставлення. Але коли ви публікуєте це посилання, я не можу не стверджувати, що це якийсь сарказм. Дуже занадто оборонний, я думаю.
Gnijuohz

Відповіді:


16

Кожен об’єкт Java має заголовок, який містить інформацію, важливу для JVM. Найважливішим є посилання на клас об’єкта (одне машинне слово), і є кілька прапорів, які використовується сміттєзбірником та для керування синхронізацією (оскільки кожен об'єкт може бути синхронізований), що займає інше машинне слово (використовуючи часткові слова бути поганим у виконанні). Отже, це 2 слова, що становить 8 байт у 32-бітових системах та 16 байт на 64-бітних. Для масивів додатково потрібно поле int для довжини масиву, що становить ще 4 байти, можливо, 8 у 64-бітових системах.

Щодо інших мов:

  • У C немає об'єктів, тому, звичайно, він не має заголовків об'єктів, але може мати заголовок на кожному окремо виділеному фрагменті пам'яті.

  • У C ++ у вас немає збирання сміття і ви не можете використовувати довільні об'єкти для синхронізації, але якщо у вас є класи з перекритими методами, кожен об’єкт має вказівник на свій vtable, як і посилання об’єкта Java на його клас. Якщо ви використовуєте розумні покажчики, які займаються збиранням сміття, їм потрібні дані по господарству.

  • Я не знаю про Python, але я впевнений, що він також потребує посилання на клас та інформацію про ведення господарства для збору сміття.


На даний момент у OpenJDK відбувається робота щодо зменшення розміру заголовків об'єктів, невеликих, але важливих кроків :-)
Martijn Verburg

У C ++ лише поліморфні класи потребують віртуальних даних. std::pair<int, float>це простий клас, якому vtable взагалі не потрібен. Як результат, він може цілком вміститися в 8 байт. Також розумним покажчикам насправді не потрібно додавати ведення господарства. Ясний зустрічний приклад std::unique_ptr<T>, який, як правило, такий же великий, як і необроблений T*(унікальний_ptr, звичайно, не робить GC).
MSalters

4
C також має накладні витрати, кожен mallocвиділений блок пам'яті потребує заголовку, який freeпотім використовується.
herby

Принаймні одна бібліотека malloc, про яку я знаю, використовує 8-байтовий заголовок у 32-бітних системах (що є 4-байтовою довжиною, укріпленою двома наборами 2-байтових вартостей, IIRC).
Стипендіати доналу
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.