Сколько памяти использует хэш-таблица?
-
07-07-2019 - |
Вопрос
В Java, если я создам Hashtable<K, V>
и поместите в него N элементов, сколько памяти он будет занимать?Если это зависит от реализации, что было бы хорошим "предположением"?
Решение
Редактировать; О боже, я идиот, я дал информацию для HashMap, а не для HashTable.Однако после проверки реализации идентичны для целей использования памяти.
Это зависит от настроек внутренней памяти вашей виртуальной машины (упаковка элементов, 32-разрядные или 64-разрядные указатели и выравнивание / размер слов) и не определяется java.
Основную информацию по оценке использования памяти можно найти здесь здесь.
Вы можете оценить это примерно так:
- На 32-разрядных виртуальных машинах указатель равен 4 байтам, на 64-разрядных виртуальных машинах он равен 8 байтам.
- Служебные данные объекта составляют 8 байт памяти (для пустого объекта, ничего не содержащего).
- Объекты дополняются до размера, кратного 8 байтам (тьфу).
- Для каждой хэш-карты существуют небольшие постоянные накладные расходы:один поплавок, 3 дюйма плюс накладные расходы на объект.
- Существует множество слотов, в некоторых из которых будут записи, некоторые из которых будут зарезервированы для новых.Отношение заполненных слотов к общему количеству слотов НЕ ПРЕВЫШАЕТ указанного коэффициента загрузки в конструкторе.
- Массиву слотов требуется один служебный объект плюс один int для размера, плюс один указатель для каждого слота, чтобы указать сохраненный объект.
- Количество слотов обычно в 1,3-2 раза больше, чем количество сохраненных сопоставлений, при коэффициенте загрузки по умолчанию 0,75, но может быть и меньше этого, в зависимости от коллизий хэшей.
- Для каждого сохраненного сопоставления требуется объект ввода.Для этого требуется один служебный объект, 3 указателя, плюс сохраненные объекты ключа и значения, плюс целое число.
Итак, собираем это вместе (для 32/64-битной JVM Sun HotSpot):HashMap требует 24 байта (само по себе, примитивные поля) + 12 байт (константа массива слотов) + 4 или 8 байт на слот + 24/40 байт на запись + размер ключевого объекта + размер объекта значения + заполнение каждого объекта кратным 8 байтам
ИЛИ, грубо говоря (при большинстве настроек по умолчанию точность не гарантируется):
- На 32-разрядной виртуальной машине:36 байт + 32 байта/ сопоставление + ключи и значения
- На 64-разрядной виртуальной машине:36 байт + 56 байт/ сопоставление + ключи и значения
Примечание:это требует дополнительной проверки, возможно, потребуется 12 байт для обработки данных объекта на 64-разрядной виртуальной машине.Я не уверен насчет нулей - указатели на нули могут быть каким-то образом сжаты.
Другие советы
Трудно оценить. Я бы прочитал это сначала: http://www.codeinstructions.com/2008/12/ Java-объекты-памяти structure.html р>
Просто используйте инструменты sunjdk, чтобы определить размер K, V и
jmap -histo [pid]
num #instances # байтовое имя класса
1: 126170 19671768 MyKClass
2: 126170 14392544 MyVClass
3: 1 200000 MyHashtable
Также вы можете использовать HashMap вместо Hashtable, если вам не нужна синхронизация.