Pierwszymi algorytmami do oczyszczania pamięci były Serial Garbage Collector i Parallel Garbage Collector, zwane są także algorytmami wysokiej przepustowości. Moduły pracują bardzo podobnie, jedyną różnicą jest liczba angażowanych wątków do zarządzania pamięcią.
W tym artykule znajdziesz odpowiedzi na poniższe pytania:
- Co to jest Parallel Garbage Collector?
- Co to jest Serial Garbage Collector?
- Czym różnią się oba moduły?
- Czym odróżnia się od innych rozwiązań?
- Jak włączyć moduł?
Charakterystyka
Moduł Serial GC charakteryzuje się pracą w trybie szeregowym. Z wpisu garbage collection wiemy, że tryb szeregowy pracuje na jednym wątku zatrzymując pozostałe wątki aplikacyjne. Moduł Parallel GC charakteryzuje się pracą w trybie równoległym, a więc zatrzymuje wszystkie wątki aplikacyjne i używa je do czyszczenia pamięci.
Oba moduły pracują i bazują na generacjach. W młodej generacji moduł używa strategii Mark-Copy, czyli kopiowania żywych obiektów do nowego miejsca na stercie. W przypadku starej generacji używa Mark-Sweep-Compact, czyli oznacza obszar zajmowany przez osiągalne obiekty, następnie usuwa obiekty porzucone w pierwszym kroku a na końcu eliminuje fragmentacje pamięci.
Dodatkowo moduł Parallel GC dzieli wątki na wykonywanie konkretnych zadań. Dla pojedynczego wątku przydziela wyczyszczenie pamięci z starej generacji, a następnie wyeliminowanie fragmentacji, zaś resztę wątków przydziela do młodej generacji w celu posprzątania pamięci.
Początkowo moduł Parallel GC pracował na jednym wątku w strefie starej generacji. Jedynie praca na młodej generacji odróżniała go od Serial GC, ponieważ tam angażował wszystkie wątki aplikacyjne. Wraz ze wzrostem rozmiarów stert Javy wzrastał czas pracy modułu GC, a co za tym idzie większe opóźnienia. W Java 6 wprowadzono poprawkę, która umożliwiała włączenie trybu równoległego podczas pracy w starej generacji. Taką opcje można było włączyć za pomocą -XX:+UseParallelOldGC. Od Java 7 opcja jest domyślnie włączona.
Moduł Parallel GC jest domyślnym algorytmem do oczyszczania pamięci w Javie 8 i do wersji 7 w server JRE. Moduł Serial GC jest domyślnym algorytmem do wersji 7 w client JRE.
Serwer JRE służy do wdrażania aplikacji Java na serwerze. Został specjalnie dostrojony i zapewnia najszybszą możliwą prędkość działania poprzez użycie Parallel GC i agresywnych algorytmów do optymalizacji aplikacji Java. Zawiera również narzędzia do monitorowania aplikacji. Client JRE zawiera podstawowe narzędzia do uruchomienia aplikacji w systemach użytkowników. Może uruchomić się szybciej i wymaga mniejszej ilości pamięci.
Tryb pracy
Algorytm pracuje w czterech fazach:
- W pierwszej fazie: algorytm szuka obiektów źródłowych, które będą korzeniami w grafie, a następie oznacza obiekty jako żywe. Korzeniem może być uruchomiony wątek albo zmienna lokalna.
- W drugiej fazie: algorytm ponownie przegląda zaznaczone korzenie, ale tym razem zaznacza wszystkie powiązane z nim obiekty jako żywe.
- W trzeciej fazie: algorytm teruje po wszystkich obiektach z pamięci i sprawdza czy taki obiekt został oznaczony jako żywy. Jeśli obiekt nie został oznaczony, to wtedy zostaje usunięty z pamięci.
- Na końcu resetuje statusy i opcjonalnie wykonuje reorganizacje pamięci, aby uniknąć fragmentacji.
W pigułce
Serial GC
- Domyślny GC do Java 7 w Client JRE
- Parametr: -XX:+UseSerialGC
- Działa w trybie szeregowym (jednowątkowy)
- Opiera się na generacjach
- Przeznaczony na sprzęt o bardzo małej mocy z aplikacjami jednowątkowymi
Parallel GC
- Domyślny GC do Java 7 w Server JRE oraz Java 8.
- Parametr: -XX:+UseParallelGC.
- Działa w trybie równoległym (wielowątkowy)
- Opiera się na generacjach
Ciekawe artykuły
- M. Marczak, Algorytmy GC. Serial, Parallel, CMS, https://bulldogjob.pl/news/424-algorytmy-gc-serial-parallel-cms
- Garbage First Overview, https://www.informit.com/articles/article.aspx?p=2496621&seqNum=2