Сколько памяти использует Hashtable? - PullRequest
9 голосов
/ 15 сентября 2009

В Java, если я создам Hashtable<K, V> и добавлю в него N элементов, сколько памяти он будет занимать? Если это зависит от реализации, что было бы хорошим «догадкой»?

Ответы [ 2 ]

14 голосов
/ 15 сентября 2009

Изменить; О боже, я идиот, я дал информацию для HashMap, а не для HashTable. Однако после проверки реализации идентичны для целей памяти.

Это зависит от настроек внутренней памяти вашей виртуальной машины (упаковка элементов, 32-битные или 64-битные указатели и выравнивание / размер слова) и не определяется java.

Базовую информацию об оценке использования памяти можно найти здесь .

Вы можете оценить это так:

  • На 32-битных виртуальных машинах указатель составляет 4 байта, на 64-битных виртуальных машинах - 8 байтов.
  • Объем служебных данных составляет 8 байт памяти (для пустого объекта, не содержащего ничего)
  • Объекты дополняются до размера, кратного 8 байтам (тьфу).
  • Для каждой хэш-карты предусмотрены небольшие постоянные издержки: одно значение с плавающей запятой, 3 дюйма плюс накладные расходы на объект.
  • Существует множество слотов, некоторые из которых будут иметь записи, некоторые из которых будут зарезервированы для новых. Отношение заполненных слотов к общему количеству слотов НЕТ БОЛЬШЕ, чем указанный коэффициент загрузки в конструкторе.
  • Массив слотов требует одного заголовка объекта, плюс один int для размера, плюс один указатель для каждого слота, чтобы указать сохраненный объект.
  • Количество временных интервалов, как правило, в 1,3-2 раза больше, чем количество сохраненных отображений, при коэффициенте загрузки по умолчанию 0,75, но может быть и меньше, в зависимости от коллизий хэшей.
  • Каждое сохраненное отображение требует объекта ввода. Для этого требуется один объект, 3 указателя, плюс сохраненные объекты ключа и значения, а также целое число.

Итак, воедино (для 32/64 битной Sun HotSpot JVM): HashMap требуется 24 байта (сам по себе, поля примитивов) + 12 байтов (константа массива слотов) + 4 или 8 байтов на слот + 24/40 байтов на запись + размер ключевого объекта + размер объекта значения + заполнение каждого объекта кратным 8 байтам

ИЛИ, приблизительно (при большинстве настроек по умолчанию, точность не гарантируется):

  • На 32-битной JVM: 36 байтов + 32 байта / отображение + ключи и значения
  • На 64-битной JVM: 36 байтов + 56 байтов / отображение + ключи и значения

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

4 голосов
/ 15 сентября 2009

Сложно оценить. Я бы прочитал это сначала: http://www.codeinstructions.com/2008/12/java-objects-memory-structure.html

Просто используйте инструменты sunjdk, чтобы определить размеры K, V и

jmap -histo [pid]

num #instances # байтовое имя класса

1: 126170 19671768 MyKClass

2: 126170 14392544 MyVClass

3: 1 200000 MyHashtable

Также вы можете использовать HashMap вместо Hashtable, если вам не нужна синхронизация.

...