Вопрос

Я хотел бы спросить о накладных расходах памяти в Java, у меня есть большой арайлист (61 770 предметов), и пытаюсь рассчитать количество памяти, предпринимаемое каждым элементом (подсчет объекта и его ArrayList), профилируя приложение, которое я получаю это После того, как все данные загружены, куча занимает ~ 25 МБ. Когда ArrayList имеет только 2 предмета, куча занимает ~ 1 МБ, так примерно:

(24 * 1024 * 1024) / 61,768 = 407 байтов.

Однако, Когда я считаю поля каждого объекта, я получаю 148 байтов (не включая ArrayList, и предполагая INT = 4, Float = 4, ссылку = 4), мне интересно узнать, откуда пришли все эти дополнительные байты ...

Я могу догадаться, что поскольку объекты, которые я хранят в ArrayList, реализует интерфейс, они хранят дополнительные значения, возможно, VM хранит функцию функции 4byse для каждого реализованного метода? Интерфейс, который они реализуют, имеют 20 функций, так и 80 байтов, на общую сумму 228 байтов, все еще не близко к измерению 400 байтов.

Любая помощь будет оценена.


Вау, спасибо за все великие ответы.

@Bolo: Спасибо за ссылку, с этим классом я измеряю ~ 350 байт на объект, поэтому я могу меньше подтвердить источник большого использования памяти.

@ Yuval A: Спасибо за эту презентацию, ценный источник информации.

@UKKO: точка отметил.

@Jayan: Прямо сейчас профилировщик NetBeans дает мне ошибки, когда я стараюсь бросить кучу, попробую позже.

Это было полезно?

Решение

Эти результаты не удивительны. JVM добавляет огромное количество накладных расходов на каждый объект.

Об одновременно вдвое больше ожидаемого размера для одного объекта, из-за накладных расходов памяти JVM, не редкость.

Эта презентация Имеет замечательный, подробный, объяснение и обзор различных использований памяти памяти структуры данных в Java.

Другие советы

ArrayList IST в основном больше, чем количество элементов. Использовать getCapacity() Чтобы получить текущий размер базового массива.

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

Как мыслительный эксперимент, если вы хотели сделать это, вы должны

  1. Выгоните свой JVM и сделайте пару глобальных GC, чтобы получить все мусор
  2. Измерьте размер кучи и понятие Java о том, сколько у него свободное пространство.
  3. Запустить свой тест
  4. GC пару раз
  5. Повторить измерения от шага № 2

После всего этого и немного математики вы будете ближе, но все еще не правы. Единственным реальным решением является фактически просить, как упомянуто, как другие люди. Или понять это от знания о реализации.

Память, потребляемая ArrayList, немного расплывчато.

Возьмите кучу дамп процесса на соответствующем этапе - после того, как значения полностью назначены. Затем используйте инструменты, такие как анализатор памяти (от Eclipse).

Вы заполняете находятся мелкие и сохраненные размеры кучи.

Как сбоку, так как вы точно знаете, сколько объектов будет в вашем арайлисте, почему бы не просто использовать массив []? Будет ли количество объектов в там изменить?

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top