Pamięć w JVM

Pamiec w JVM

W tym artykule znajdziesz odpowiedzi na poniższe pytania:

  • Jaki jest podział obszaru pamięci w JVM?
  • Czym jest sterta? Jakie dane przechowuje sterta?
  • Czym jest stos? Co JVM przechowuje na stosie?

Całą pamięć dzieli się na kilka poziomów. Podstawowym podziałem obszaru pamięci w wirtualnej maszyny Javy jest podział na: sterta i dane poza stertą (pamięć natywną).

Obszar pamięci wirtualnej maszyny Java

Pamięć natywna

W dość mocnym uproszczeniu, w pamięci poza stertą umieszczone są byty potrzebne do wsparcia działania wirtualnej maszyny i reprezentacji jej struktur wewnętrznych. Możemy ją podzielić na 2 grupy: pamięć współdzielona i autonomiczna.

Pamięć współdzielona dzieli się na dodatkowe segmenty: segment Metaspace i segment Code cache.  W segmencie Metaspace przechowywane są dane statyczne takie jak: kody klas, metody, pola, literały znakowe, referencje czy stałe. W segmencie Code cache przechowywane są zoptymalizowane i skompilowane kody aplikacji. Ten segment jest mocno powiązany z modułem kompilatora Just-in-Time, który szerzej będzie omówiony w kolejnym artykule.

Kolejną grupą pamięci natywnej jest pamięć autonomiczna, czyli pamięć przypisana do każdego wątku działającego na maszynie wirtualnej. Zawiera ramki wywołań, zmienne lokalne i referencję do aktualnie wykonywanej instrukcji kodu. Schemat pamięci został zaprezentowany poniżej.

Schemat pamięci poza stertą

Sterta

Drugą i bardziej interesującą częścią pamięci jest sterta. To właśnie tutaj przechowywane są wszystkie instancje klas utworzone w trakcje wykonywania programu. Sterta ma największy wpływ na wydajność aplikacji niezależnie od wybranego języka programowania, ponieważ pamięć w stercie dość często może się zmieniać, ulegać fragmentacji i przepełniać. Obszar pamięci może rosnąć wraz z przydzielaniem i zwiększaniem zasobów dla wirtualnej maszyny Java.  Ze względu na konieczność przeglądania całej tej powierzchni, zarządzania nią i w obawie o wydajność aplikacji to podzielono stertę na generacje. Stertę dzieli się na dwie części: przestrzeń dla nowych i starych obiektów, tak jak pokazano to na rysunku poniżej.

Schemat sterty

Dodatkowo przestań dla nowych obiektów dzielona jest na podprzestrzenie:

  • Eden,
  • przestrzeń przetrwalników 0,
  • przestrzeń przetrwalników 1.

Początkową przestrzenią, przez którą każdy obiekt musi przejść jest Eden. W tym obszarze żyją nowe obiekty. Wraz z działaniem aplikacji, poszczególne obszary będą się zapełniać, aż do momentu uruchamiania mechanizmu oczyszczania pamięci. Mechanizm oczyszczania pamięci usunie nieużywane obiekty w konkretnym obszarze i awansuje do następnej generacji. W każdej z tych części można obrać inną strategię usuwania obiektów i promowania do wyższej generacji. Takie podejście wychodzi z dwóch założeń:

  • większość obiektów szybko staje się nieużyteczna z punktu widzenia aplikacji,
  • odwołania starych obiektów do nowych są bardzo rzadkie.

Ciekawe artykuły

  1. D. Rudczyk, Obszary pamięci Maszyny Wirtualnej Javy (JVM), https://softwareskill.pl/obszary-pamieci-maszyny-wirtualnej-javy-jvm
  2. J.Kubryński, Co każdy programista Java powinien wiedzieć o JVM, https://bottega.com.pl/pdf/materialy/jvm/jvm1.pdf

Dodaj komentarz

Twój adres e-mail nie zostanie opublikowany. Wymagane pola są oznaczone *