Размеры массивов в Java
Размеры объектов в Java уже обсуждались на Хабре, например, здесь или здесь. Мне бы хотелось подробнее остановиться на размерах многомерных массивов — простая вещь, которая для меня стала неожиданной.
Оптимизируя вычислительный алгоритм по памяти, я наткнулся на то, что при определённых (вполне разумных) входных параметрах создаётся массив float[500][14761][2]. Сколько он может занимать в памяти (на HotSpot 1.6.0_26 32bit, если кому интересно)? Я примерно прикинул, что
Я поискал, что на эту тему пишут в Интернете, и наткнулся на довольно понятную статью на английском «How to calculate the memory usage of a Java array». Вкратце суть изложения такая:
- Всякий Java-объект имеет оверхед 8 байт;
- Java-массив имеет дополнительный оверхед 4 байта (для хранения размера);
- Ссылка имеет размер 4 байта;
- Размер всех объектов выровнен по 8 байт;
- Многомерный массив — это массив ссылок на массивы.
Этого знания достаточно. Итак мы имеем в конце цепочки массивы float[2]. Их размер — это 2 float (по 4 байта) + 12 байт оверхеда — 20 байт. Выравниваем до 8 — получается 24 байта. Всего у нас таких массивов создано в куче
Затем у нас есть массивы float[14761][] — массивы из
Наконец, у нас есть собственно тот массив, который мы завели — float[500][][] — массив из 500 ссылок на двумерные массивы. Он занимает
Складываем, что получилось:
Сразу же пришло в голову очевидное решение: упорядочить измерения массива по возрастанию. Сделаем float[2][500][14761] и алгоритм от этого никак не пострадает. Какой размер получится в этом случае?
- Массивы float[14761]:
14 761*4+12 =59 056 байт, всего1 000 таких массивов, итого59 056 000 байт. - Массивы float[500][]:
500*4+12 =2 012 , после выравнивания —2 016 , всего 2 таких массива, итого4 032 байта. - Массив float[2][][]:
2*4+12 = 20, после выравнивания — 24 байта.
В сумме
Отсюда следует правило большого пальца: если размеры массива по измерениям хотя бы примерно известны заранее, следует упорядочивать измерения по возрастанию. Кроме того, обязательно используйте анализаторы памяти: узнаете много нового о своей программе.