Praca z generacjami obiektów

Odśmiecacze Java implementują pokoleniową strategię wyrzucania elementów bezużytecznych, która może klasyfikować obiekty według wieku.

Taką potrzebę (oznaczania i kompaktowania wszystkich obiektów) w JVM można nazwać nieefektywną. Ponieważ przydzielana jest duża liczba obiektów, ich lista rośnie, co prowadzi do wydłużenia czasu zbierania elementów bezużytecznych. Empiryczna analiza aplikacji wykazała, że ​​większość obiektów w Javie jest krótkotrwała.

Obszar pamięci sterty w JVM jest podzielony na trzy sekcje:

Praca z generacjami obiektów

Młodsza generacja

Nowo utworzone obiekty zaczynają się w młodszym pokoleniu. Młodsze pokolenie dzieli się dalej na dwie kategorie.

  • Eden Space - Wszystkie nowe obiekty zaczynają się tutaj, mają przydzieloną pamięć początkową.
  • Przestrzenie ocalałych (FromSpace i ToSpace) - Obiekty są przenoszone tutaj z Edenu po przetrwaniu jednego cyklu zbierania śmieci.

Proces, w którym obiekty są usuwane bezużytecznie z młodszego pokolenia, jest nazywany pomniejszym zdarzeniem wyrzucania elementów bezużytecznych.

Kiedy przestrzeń Edenu jest wypełniona przedmiotami, przeprowadzana jest mała zbiórka śmieci. Wszystkie martwe obiekty są usuwane, a żywe są przenoszone na jedno z dwóch pozostałych pól. Mały GC sprawdza również obiekty na polu ocalałego i przenosi je na inne (następne) pole ocalałego.

Weźmy jako przykład następującą sekwencję.

  1. W Edenie znajdują się obiekty obu typów (żywe i martwe).
  2. Następuje mały GC - wszystkie martwe obiekty są usuwane z Edenu. Wszystkie żywe obiekty są przenoszone na pole-1 (FromSpace). Eden i przestrzeń-2 są teraz puste.
  3. Nowe obiekty są tworzone i dodawane do Edenu. Niektóre obiekty w Edenie i przestrzeni-1 stają się martwe.
  4. Następuje mały GC - wszystkie martwe obiekty są usuwane z Edenu i przestrzeni-1. Wszystkie żywe obiekty są przenoszone do przestrzeni-2 (ToSpace). Eden i przestrzeń-1 są puste.

Dlatego w dowolnym momencie jedno z pól ocalałych jest zawsze puste. Kiedy ocaleni osiągną określony próg poruszania się po polach ocalałych, przechodzą do starszej generacji.

Możesz użyć flagi -Xmn , aby ustawić rozmiar młodej generacji .

Starsze pokolenie

Obiekty, które żyją przez znaczną ilość czasu (na przykład większość czasu życia programu), ostatecznie stają się obiektami starszymi — stulatkami. Jest również znany jako generacja zwykła i zawiera obiekty pozostawione w Przestrzeń Przetrwania przez długi czas.

Próg życia obiektu określa, ile cykli wyrzucania elementów bezużytecznych musi przejść, zanim zostanie przeniesiony do starszej generacji. Proces, w którym obiekty są wysyłane do śmieci ze starszej generacji, nazywany jest głównym zdarzeniem wyrzucania elementów bezużytecznych.

Możesz użyć flag -Xms i -Xmx , aby ustawić początkową i maksymalną wielkość pamięci sterty .

Ponieważ Java używa generacyjnego wyrzucania elementów bezużytecznych, im więcej zdarzeń usuwania elementów bezużytecznych doświadcza obiekt, tym dalej porusza się na stercie. Zaczyna w młodszym pokoleniu i ostatecznie kończy w zwykłym pokoleniu, jeśli żyje wystarczająco długo.

Aby zrozumieć promocję obiektów między przestrzeniami i pokoleniami, rozważ następujący przykład:

Tworzony obiekt jest najpierw umieszczany w przestrzeni Edenu młodego pokolenia.

Gdy tylko nastąpi mała zbiórka śmieci, żywe obiekty z Edenu są przenoszone do FromSpace. Kiedy następuje kolejna pomniejsza zbiórka śmieci, żywe obiekty zarówno z Edenu, jak i kosmosu są przenoszone do ToSpace.

Ten cykl powtarza się określoną liczbę razy. Jeśli po tym momencie obiekt nadal jest „w eksploatacji”, następny cykl wyrzucania elementów bezużytecznych przeniesie go do przestrzeni starszej generacji.

Trwałe generowanie i metaprzestrzeń

Metadane, takie jak klasy i metody, są przechowywane w trwałym generowaniu. JVM zapełnia go w czasie wykonywania na podstawie klas używanych przez aplikację. Klasy, które nie są już używane, mogą przejść z trwałego generowania do śmieci.

Możesz użyć flag -XX:PermGen i -XX:MaxPermGen , aby ustawić początkowy i maksymalny rozmiar trwałej generacji .

metaprzestrzeń

Od wersji Java 8 przestrzeń PermGen została zastąpiona przestrzenią pamięci MetaSpace. Implementacja różni się od PermGen - ta przestrzeń sterty jest teraz zmieniana automatycznie.

Pozwala to uniknąć problemu braku pamięci aplikacji, który występuje z powodu ograniczonego rozmiaru przestrzeni sterty PermGen. Pamięć metaprzestrzeni może być usuwana bezużytecznie, a klasy, które nie są już używane, zostaną automatycznie wyczyszczone, gdy metaprzestrzeń osiągnie maksymalny rozmiar.