Подтвердить что ты не робот

Какова стоимость хранения вложенного примитива в Java?

Насколько велика, в байтах, это примитив в виде бокса, такой как java.lang.Integer или java.lang.Character в Java?

An int - 4 байта, типичный указатель также 4 байта (если не сжат JVM). Является ли стоимость для целого (без кеширования) таким образом 4 bytes + 4 bytes = 8 bytes? Есть ли еще какие-либо скрытые поля в полевом объекте или дополнительные накладные расходы, связанные с объектами (т.е. Общая стоимость объектов, о которых я не знаю?).

Я не интересуюсь проблемами кеширования. Я знаю, что целые числа в определенном диапазоне кэшируются JVM.

Можно перефразировать вопрос: каков максимальный коэффициент, который нужно умножить на объем памяти, используемый для значений в штучной упаковке по сравнению с примитивными значениями?

EDIT: Я понимаю, что существует множество реализаций JVM. Какова типичная стоимость типичной 32-битной реализации HotSpot?

4b9b3361

Ответ 1

Это реализация определена, поэтому нет конкретного ответа. Но я должен был бы ответить на него для Hotspot.

Что вам нужно знать: Hotspot всегда выравнивает объекты на границах 8 байт. Кроме того, для каждого объекта есть 2 слова. [1]

Если положить это вместе, получим:

32-битная виртуальная машина: 4 байта целое число + 2 слова заголовок объекта = 12 байт. Это не кратно 8, поэтому в результате затраты на 1 целое число составляют следующий кратный 8: 16 байт.

64-битная виртуальная машина: 4 байта целое число + 2 слова = 20 байт. Округление снова: размер 24 байта.

Размер ссылки, очевидно, не играет в размер самого объекта, за исключением того, что он имеет ссылки на другие объекты, что не относится к простой обертке int. Если бы это было так, у нас было бы 4 байта для каждой ссылки для 32 бит и 4 байта для кучи <= 32gb с CompressedOops на современных JVM (в противном случае 8 байт) для 64-битных JVM.

[1] Заинтересованные люди могут посмотреть код в share/vm/oops/oop.hpp

Ответ 2

Это больше, чем это.

Каждая ссылка на объект имеет дополнительные накладные расходы, например ссылку на класс. Кроме того, ваш 4-байтовый указатель не совсем точен. Это ссылка, поэтому это идентификатор плюс указатель, И этот указатель может быть 8 байтов, если вы находитесь на 64-битной JVM.

Также существуют различия в реализации VM. Лучший способ убедиться в этом - это подтянуть его в профилировщике.

Моя оценка (Super SWAG) будет. Ссылка на объект 16 байтов (64-разрядная JVM) Ссылка на класс 16 байт примитивное значение 4 байта (предположим int.) Всего. 36 байт.

EDIT: теперь, когда вы укажете 32-битную JVM, мой SWAG будет 20 байтов, используя ту же самую математику.

Ответ 3

Я знаю, что это точно не отвечает на вопрос о стоимости хранения вложенных в бокс примитивов, но я чувствую от вашего вопроса, что вы спрашиваете, оправданно ли ваше использование.

Вот выдержка из Effective Java (2nd Edition) Джошуа Блоха, которая поможет вам решить:

"So when should you use boxed primitives? They have several legitimate uses. The first is as elements, keys, and values in collections. You can’t put primitives in collections, so you’re forced to use boxed primitives. This is a special case of a more general one. You must use boxed primitives as type parameters in parame- terized types (Chapter 5), because the language does not permit you to use primi- tives. For example, you cannot declare a variable to be of type Thread- Local<int>, so you must use ThreadLocal<Integer> instead. Finally, you must use boxed primitives when making reflective method invocations (Item 53).

In summary, use primitives in preference to boxed primitives whenever you have the choice. Primitive types are simpler and faster. If you must use boxed primitives, be careful! Autoboxing reduces the verbosity, but not the danger, of using boxed primitives. When your program compares two boxed primitives with the == operator, it does an identity comparison, which is almost certainly not what you want. When your program does mixed-type computations involving boxed and unboxed primitives, it does unboxing, and when your program does unboxing, it can throw a NullPointerException. Finally, when your program boxes primitive values, it can result in costly and unnecessary object creations."

Надеюсь, что это поможет.