Насколько велика ссылка на объект?

Каков размер, который потребляет ссылка в Android Java VM?

Больше информации:

Под этим я подразумеваю, если у нас есть

String str = "Watever";

Мне нужно то, что берет str, а не "Watever". -- "Watever" - это то, что сохраняется в месте, на которое указывает указатель (или ссылка), удерживаемый str.

Также, если у нас есть

String str = null;

сколько памяти потребляет? Это то же самое, что и другие str?

Теперь, если у нас есть:

Object obj[] = new object[2];

сколько потребляет obj и сколько потребляют obj[1] и obj[2]?


Причина вопроса следующая: (на случай, если кто-то может что-то порекомендовать).

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

При отображении этих изображений в галерее я использовал поиск изображения в списке (МЕДЛЕННО), а затем, если изображения не было, я показывал временную загрузку изображения, пока изображение не было загружено.

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

Как я объяснял ранее, этот поиск происходит в потоке пользовательского интерфейса (и я не могу это изменить). Из-за этого коллизии могут стать проблемой, если они начнут замедлять поток.

Я читал, что для баланса эффективности времени и пространства хэш-таблица должна быть заполнена примерно наполовину, но это приводит к коллизиям в половине случаев (непрактично для потока пользовательского интерфейса). Это заставляет меня задуматься об очень длинной хеш-таблице (по сравнению с количеством сохраненных изображений) и использовать больше оперативной памяти (имея меньше свободного VMHeap).

Прежде чем определить размер хеш-таблицы, я хотел узнать, сколько памяти она будет потреблять, чтобы не преувеличивать.

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


Прежде чем задать этот вопрос, я искал среди других мест в

Насколько велик является ссылкой на объект в Java и какую именно информацию она содержит?

размер ссылочного типа в java

Учебник по хэшированию

(Да, я знаю, что два места противоречат друг другу, это одна из причин вопроса).


person J-Rou    schedule 30.04.2011    source источник


Ответы (2)


Ссылка на объект или массив занимает одно 32-битное слово (4 байта) на 32-битной JVM или Davlik VM. null занимает то же место, что и ссылка. (Это необходимо, потому что нуль должен соответствовать слоту ссылочного типа, т. е. поле экземпляра, локальная переменная и т. д.)

С другой стороны, объект занимает не менее 2 32-битных слов (8 байтов), а массив занимает не менее 3 32-битных слов (12 байтов). Фактический размер зависит от количества и типов полей для объекта и от количества и типа элементов для массива.


Для 64-битной JVM размер ссылки составляет 64 бита, если вы не настроили JVM для использования сжатых указателей:

-XX:+UseCompressedOops Позволяет использовать сжатые указатели (ссылки на объекты, представленные в виде 32-битных смещений вместо 64-битных указателей) для оптимизации 64-битной производительности с размерами кучи Java менее 32 ГБ.


Я думаю, это суть вашего вопроса.

Прежде чем определить размер хеш-таблицы, я хотел узнать, сколько памяти она будет потреблять, чтобы не преувеличивать.

Если вы выделяете HashMap или Hashtable с большим начальным размером, большая часть пространства будет занята хэш-массивом. Это массив ссылок, поэтому размер будет 3 + initialSize 32-битных слов. Маловероятно, что это будет иметь значение... если только вы не ошибетесь в оценке размера.

Однако я думаю, что вы, вероятно, излишне беспокоитесь о производительности. Если вы храните объекты в выделенном по умолчанию HashMap или Hashtable, класс автоматически изменит размер хеш-таблицы по мере ее увеличения. Таким образом, при условии, что ваши объекты имеют достойную хеш-функцию (не слишком медленную, не хэширующую все до небольшого количества значений), хэш-таблица не должна быть прямой проблемой производительности процессора.

person Stephen C    schedule 30.04.2011
comment
Спасибо. Это решает мою проблему. Но только для лучшего понимания. Не могли бы вы объяснить немного больше в массивах. Если бы у меня был массив, скажем, Object[2], он занял бы 3 слова + 2 слова для каждого объекта (3 + 2 * 2 = 7 слов)?? - person J-Rou; 30.04.2011
comment
Нет. Потребуется 3 слова для заголовка массива + 1 слово для каждого элемента; то есть 5 слов. (Массив содержит ссылки на объекты, а не на фактические объекты.) - person Stephen C; 30.04.2011
comment
Спасибо или за вторую часть, и за комментарий тоже, я никогда раньше не использовал хеш-таблицы, поэтому вторая часть действительно помогла. - person J-Rou; 30.04.2011
comment
Как насчет общих объектов? Они также используют 3 слова? - person HopefullyHelpful; 09.09.2015
comment
Хорошо, я думаю, что общие объекты также используют только 2 слова из-за стирания типа. - person HopefullyHelpful; 09.09.2015
comment
Универсальные объекты имеют точно такое же представление во время выполнения, что и неуниверсальные объекты... включая размер заголовков объектов. - person Stephen C; 09.09.2015
comment
(Обычные и неуниверсальные объекты обычно имеют заголовки из 2 слов. Разница в том, что объект, не являющийся массивом, не имеет / не нуждается в поле length.) - person Stephen C; 08.06.2017

Ссылки практически бесплатны. Тем более по сравнению с картинками.

Наличие нескольких столкновений на карте не является реальной проблемой. Коллизии могут быть разрешены гораздо быстрее, чем линейный поиск по списку элементов. Тем не менее, двоичный поиск по отсортированному списку элементов был бы хорошим способом снизить использование памяти (по сравнению с картой).

Я могу поручиться за эффективность использования меньших начальных размеров для Карт — недавно я написал программу, которая создает структуру Trie из 170 000 английских слов. Когда я установил начальный размер 26, у меня кончилась память к тому времени, когда я добрался до слов, начинающихся с R. Сократив его до 5, я смог создавать карты без проблем с памятью и мог выполнять поиск по дереву (со многими столкновения) практически мгновенно.

[Изменить] Если ссылка имеет размер 32 бита (4 байта), а размер вашего среднего изображения составляет около 2 мегабайт, вы можете разместить 500 000 ссылок в том же пространстве, что и одно изображение. Вам не нужно беспокоиться о ссылках.

person Haphazard    schedule 30.04.2011
comment
Большое спасибо. Я даю ответ Стивену С, потому что он отвечает на точный вопрос, но я даю вам +1, потому что вы подтвердили то, что я думал, и дали мне хороший пример на хеш-таблице (я никогда ее не создавал) . Я думаю, что этот вопрос помогает мне так же много. - person J-Rou; 30.04.2011
comment
Кроме того, мой средний размер изображения составляет 60 КБ, поэтому может поместиться около 7500 32-битных ссылок. Это более чем достаточно. - person J-Rou; 30.04.2011