Ile on waży?!

Czy zastanawialiście się kiedyś jak dużo pamięci zajmują obiekty w Javie? Dużo osób pewnie nigdy się nad tym nie głowiło, a przynajmniej nie przed pierwszym OutOfMemoryError 😉

W tym wpisie postaram się pokazać w jaki sposób oszacować wielkość obiektów, które tworzymy w Javie.

Typy prymitywne

Niewątpliwie najłatwiej jest określić ilość pamięci zajmowanej przez typy prymitywne. Poniżej przedstawiam tabelkę, która pokazuje ile każdy z typów potrzebuję bajtów w pamięci.

Typbajty
boolean1
byte1
char2
int4
float4
long8
double8

Ilość pamięci potrzebnej do przechowywania booleana może trochę dziwić. W końcu może on przyjąć tylko dwa wartości i w teorii powinien zajmować 1 bit. Specyfikacja JVM nie definiuje ile pamięci jest potrzebne na przechowanie booleana i zależy to od danej implementacji. Dla uproszczenia możemy śmiało przyjąć, że jest potrzebny 1 bajt.

Reszta wartości wydaję się być w miarę oczywista 🙂

Tablice

Każda tablica zajmuje wielokrotność danego typu (co wydaję się oczywiste ;)) oraz dodatkowe 24 bajty, które są narzutem tablicy. Poniżej przedstawiam tabelkę z przykładami, które powinny wszystko wyjaśnić.

Typbajty
byte[]N + 24
char[]2N+24
int[]4N+24
double[]8N+24

Obiekty

I teraz przechodzimy do mięsa tematu  – czyli jak oszacować wielkość obiektu naszej klasy.

Aby to zrobić potrzebujemy kilku dodatkowych informacji.

Narzut obiektu

Każdy obiekt, podobnie jak tablica, powoduje dodatkowy narzut pamięci. W tym przypadku jest to 16 bajtów.

Referencja

Każda przetrzymywana referencja w naszym obiekcie to dodatkowe 8 bajtów.

Padding

Wielkość każdego obiektu jest uzupełniana do wielokrotności 8 bajtów.

Praktyka 🙂

Jako przykład weźmy klasę String. Poniżej przedstawiam wycinek implementacji tej klasy, który jest potrzebny do oszacowania wielkości obiektu.

Do obliczenia potrzebujemy zsumować kilka rzeczy:

  1. Narzut obiektu – 16 bajtów
  2. Referencja do tablicy – 8 bajtów
  3. Tablica – 2N + narzut tablicy 24 bajty
  4. Pole offset – 4 bajty
  5. Pole count – 4 bajty
  6. Pole hash – 4 bajty

Zsumowując wszystko wychodzi nam 2N + 60 bajtów. W takim przypadku musimy jeszcze pamiętać o paddingu, czyli dodajemy 4 bajty, aby całkowita wielkość obiektu była wielokrotnością 8.

Podsumowanie

Powyżej przedstawiłem ogólne zasady, których możemy użyć, aby oszacować wielkość naszych obiektów w Javie. Dzięki temu możemy lepiej zrozumieć co jest alokowane w pamięci i jaki rozmiar zajmuje.

← Previous post

Next post →

1 Comment

  1. I see you don’t monetize lantkowiak.pl, don’t waste your traffic,
    you can earn additional cash every month with new monetization method.
    This is the best adsense alternative for any type of
    website (they approve all sites), for more details simply search in gooogle: murgrabia’s tools

Dodaj komentarz

Twój adres email nie zostanie opublikowany. Pola, których wypełnienie jest wymagane, są oznaczone symbolem *