2009-09-15 15 views
9

W języku Java, jeśli utworzę Hashtable<K, V> i umieścić w nim elementy N, ile pamięci zajmie? Jeśli jest to zależne od wdrożenia, co byłoby dobrym "domysłem"?Ile pamięci używa tablica HashTable?

+0

Prawdopodobnie będzie zdominowany przez rozmiar klucza i obiektów wartości (z wyjątkiem małych map). –

+0

Dodałem dokładne obliczenia, chociaż może się to różnić w przypadku maszyny wirtualnej. To nie zawsze prawda. Przy bardzo małych klawiszach i wartościach (powiedzmy, z obiektami otoki dla prymitywów) rozmiar obiektów Entry może dominować w rozmiarze hashmap/hashtable (wewnętrznie są one takie same). Może się to również zdarzyć, jeśli wiele wartości jest odniesieniami do tej samej instancji obiektu. Jeśli używasz wielu obiektów pierwotnych jako kluczy lub wartości, zajrzyj do biblioteki Trove. Jest to szybsze i bardziej wydajne pod względem pamięci. – BobMcGee

Odpowiedz

12

Edytuj; Oh geez, jestem idiotą, podałem informacje o HashMap, a nie HashTable. Jednak po sprawdzeniu implementacje są identyczne dla celów pamięci.

Jest to zależne od konfiguracji wewnętrznej pamięci VM (pakowanie elementów, wskaźniki 32-bitowe lub 64-bitowe oraz wyrównanie/rozmiar tekstu) i nie jest określone przez java.

Podstawowe informacje na temat szacowania wykorzystania pamięci można znaleźć pod adresem here.

Można oszacować go tak:

  • Na 32-bitowych maszyn wirtualnych, to wskaźnik wynosi 4 bajty, na 64-bitowych maszyn wirtualnych, to jest 8 bajtów.
  • górny obiektu ma 8 bajtów pamięci (dla pustego przedmiotu, zawierające nic)
  • Obiekty są wypełnione do wielkości, która jest wielokrotnością 8 bajtów (ble).
  • Istnieje niewielka, stała wartość szczytowa dla każdej mieszającej się funkcji: jeden ruchomy, 3 wewnętrzne i dodatkowy obiekt.
  • Istnieje szereg gniazd, z których niektóre będą miały pozycje, z których niektóre będą zarezerwowane dla nowych. Stosunek napełnionych szczelin do łącznych szczelin NIE MA więcej niż określony współczynnik obciążenia w konstruktorze.
  • Tablica slotów wymaga jednego obiektu narzutowego, plus jeden int dla rozmiaru, plus jeden wskaźnik dla każdego gniazda, aby wskazać przechowywany obiekt.
  • Liczba gniazd jest zwykle od 1,3 do 2 razy większa niż liczba zapisanych odwzorowań, przy domyślnym współczynniku obciążenia 0,75, ale może być mniejsza od tej, w zależności od kolizji mieszania.
  • Każde zapisane odwzorowanie wymaga obiektu wejściowego. Wymaga to narzutu jednego obiektu, 3 wskaźników, a także przechowywanych obiektów kluczy i wartości oraz liczby całkowitej.

więc wprowadzenie go wraz (32/64 nieco Sun HotSpot JVM) HashMap po 24 bajtów (siebie, pola primtive) + 12 bajtów (szczelina stałe tablica) + 4 lub 8 bajtów na gnieździe + 24/40 bajtów na wejściu + rozmiar klucza przedmiot + wartość rozmiaru obiektu + dopełnienie każdego obiektu na wielokrotność 8 bajtów

OR, w przybliżeniu (w większości ustawień domyślnych, nie gwarantuje być dokładne):

  • W 32-bitowym JVM: 36 bajtów + 32 bajtów/mapowania + klucze & wartości
  • W 64-bitowym JVM: 36 bajtów + 56 bajtów/mapowania + klucze & Wartości

Uwaga: to wymaga więcej sprawdzania, może potrzebować 12 bajtów dla obiektu narzutowego w 64-bitowej maszynie wirtualnej. Nie jestem pewien o wartościach null - wskaźniki dla wartości null mogą być w jakiś sposób skompresowane.

4

Trudno oszacować. Chciałbym przeczytać ten pierwszy: http://www.codeinstructions.com/2008/12/java-objects-memory-structure.html

Wystarczy użyć narzędzia sunjdk dowiedzieć się o wielkości K, V i

jmap -histo [pid]

num #instances #bytes Class Nazwa

1: 126170 19671768 MyKClass

2: 126170 14392544 MyVClass

3: 1 200000 MyHashtable

Możesz również użyć HashMap zamiast HashTable, jeśli nie potrzebujesz synchronizacji.

Powiązane problemy