Co to jest garbage collector w Javie?

104

Jestem nowy w Javie i jestem zdezorientowany co do garbage collectora w Javie. Co tak naprawdę robi i kiedy zaczyna działać. Proszę opisać niektóre właściwości garbage collectora w Javie.

Subhransu Mishra
źródło
2
możliwy duplikat Garbage Collection
Ian Ringrose
10
Czasami lepiej jest przeczytać rozdział w dobrej książce, oczekując zrozumienia złożonego tematu od odpowiedzi na jedno pytanie.
Ian Ringrose
4
@Ian To podobne pytanie, ale nie jest to duplikat. I to pytanie cuchnie pracą domową.
NullUserException

Odpowiedzi:

119

Śmieciarza to program, który działa na Java Virtual Machine , który pozbywa się obiektów, które nie są używane przez aplikację Java anymore. Jest to forma automatycznego zarządzania pamięcią .

Gdy uruchomiona jest typowa aplikacja Java, tworzy nowe obiekty, takie jak Strings i Files, ale po pewnym czasie te obiekty nie są już używane. Na przykład spójrz na następujący kod:

for (File f : files) {
    String s = f.getName();
}

W powyższym kodzie element String sjest tworzony przy każdej iteracji forpętli. Oznacza to, że w każdej iteracji przydzielana jest niewielka ilość pamięci, aby utworzyć Stringobiekt.

Wracając do kodu, widzimy, że po wykonaniu pojedynczej iteracji w kolejnej iteracji Stringobiekt, który został utworzony w poprzedniej iteracji, nie jest już używany - obiekt ten jest teraz uważany za „śmieci”.

W końcu zaczniemy zbierać dużo śmieci, a pamięć będzie używana dla obiektów, które nie są już używane. Jeśli to się powtórzy, w końcu wirtualnej maszynie Javy zabraknie miejsca na tworzenie nowych obiektów.

Tutaj wkracza śmieciarz.

Odśmiecacz będzie szukał obiektów, które nie są już używane, i usunie je, zwalniając pamięć, aby inne nowe obiekty mogły korzystać z tego fragmentu pamięci.

W Javie zarządzaniem pamięcią zajmuje się garbage collector, ale w innych językach, takich jak C, zarządzanie pamięcią trzeba wykonać samodzielnie, używając funkcji takich jak mallocifree . Zarządzanie pamięcią to jedna z tych rzeczy, w których łatwo popełniać błędy, co może prowadzić do tak zwanych wycieków pamięci - miejsc, w których pamięć nie jest odzyskiwana, gdy nie jest już używana.

Automatyczne schematy zarządzania pamięcią, takie jak wyrzucanie elementów bezużytecznych, sprawiają, że programista nie musi się tak bardzo martwić o kwestie związane z zarządzaniem pamięcią, dzięki czemu może bardziej skupić się na tworzeniu aplikacji, których potrzebuje.

coobird
źródło
Czy byłoby prawdą, gdyby aplikacja Java uruchomiona na komputerze miała dwie funkcje czyszczenia pamięci. Jeden z wirtualną maszyną Java. A potem jeden na prawdziwym komputerze z systemem Windows? (Lub jakikolwiek inny system operacyjny)
Lealo
Nie, zazwyczaj aplikacje Java działają tylko wtedy, gdy obecne jest środowisko JRE. Zatem wymagana jest tylko funkcja czyszczenia pamięci maszyny JVM! @Lealo
Am_I_Helpful
18

Zwalnia pamięć przydzieloną obiektom, które nie są już używane przez program - stąd nazwa „śmieci”. Na przykład:

public static Object otherMethod(Object obj) {
    return new Object();
}

public static void main(String[] args) {
    Object myObj = new Object();
    myObj = otherMethod(myObj);
    // ... more code ...  
}

Wiem, że jest to niezwykle wymyślone, ale tutaj po wywołaniu utworzonego otherMethod()oryginału Objectstaje się nieosiągalny - i to jest „śmieci”, które są zbierane.

W Javie GC działa automatycznie, ale możesz również wywołać go jawnie za pomocą System.gc()i spróbować wymusić główne czyszczenie pamięci. Jak podkreśla Pascal Thivent, naprawdę nie powinieneś tego robić, a może to przynieść więcej szkody niż pożytku (zobacz to pytanie ).

Więcej informacji można znaleźć we wpisie na Wikipedii dotyczącym wyrzucania elementów bezużytecznych i tuningu zbierania śmieci (od Oracle)

NullUserException
źródło
1
AFAIK System.gc()nie zmusza GC do uruchomienia.
Itay Karo
1
+1 za dobry przykład kodu. Zauważ, że jest to całkowicie poprawne dla GC, aby zniszczyć myObjprzed wywołaniem otherMethod, ponieważ myObjnie jest już dostępny w tym momencie.
Billy ONeal
@Włochy Uważam, że jest to specyficzne dla implementacji.
NullUserException
2
Uważam, że nie należy dzwonić System.gc(), chodzi o to, aby mieć GC nie trzeba tego robić.
Pascal Thivent
z analizą ucieczki ( en.wikipedia.org/wiki/Escape_analysis ) możliwe, że JVM może nawet nie przydzielić obiektu na pierwszym miejscu w tym przykładzie. Całe tworzenie obiektów można (w teorii) zoptymalizować. Oczywiście zależne od realizacji.
mikera
15

Obiekt kwalifikuje się do wyrzucania elementów bezużytecznych lub GC, jeśli nie jest osiągalny z żadnych wątków na żywo ani przez żadne statyczne odwołania.

Innymi słowy, można powiedzieć, że obiekt kwalifikuje się do czyszczenia pamięci, jeśli wszystkie jego odwołania są zerowe. Zależności cykliczne nie są liczone jako referencje, więc jeśli obiekt A ma odniesienie do obiektu B, a obiekt B ma odniesienie do obiektu A i nie ma żadnego innego odniesienia na żywo, wówczas oba obiekty A i B będą kwalifikować się do wyrzucania elementów bezużytecznych.


Heap Generations for Garbage Collection -

Obiekty Java są tworzone Heapi Heapdzielone na trzy części lub generacje w celu zbierania śmieci w Javie, nazywane są one młodą (nową) generacją, pokrytą (starą) generacją i obszarem permu sterty.

Przestrzeń sterty Java Nowa generacja jest dalej podzielona na trzy części znane jako przestrzeń Edenu, przestrzeń Survivor 1 i Survivor 2. Kiedy obiekt po raz pierwszy utworzony w stercie, zostaje utworzony w nowej generacji w przestrzeni Edenu, a po kolejnym drobnym zbieraniu śmieci, jeśli obiekt przeżyje, zostaje przeniesiony do ocalałego 1, a następnie do ocalałego 2, zanim główny proces usuwania śmieci przeniósł ten obiekt do starej lub utrwalonej generacji .

Przestrzeń stała Java Heap to miejsce, w którym JVM przechowuje metadane dotyczące klas i metod, puli ciągów i szczegóły na poziomie klasy.

Heap Generations for Garbage Collection

Więcej informacji znajdziesz tutaj: Garbage Collection


Nie można zmusić maszyny JVM do uruchomienia funkcji Garbage Collection, chociaż można złożyć żądanie przy użyciu metody System.gc()lub Runtime.gc().

W java.lang.System

public static void gc() {
    Runtime.getRuntime().gc();  
}

W java.lang.Runtime

public native void gc();  // note native  method

Algorytm zaznaczania i zamiatania -

Jest to jeden z najpopularniejszych algorytmów używanych przez zbieranie śmieci. Każdy algorytm czyszczenia pamięci musi wykonywać 2 podstawowe operacje. Po pierwsze, powinien być w stanie wykryć wszystkie nieosiągalne obiekty, a po drugie, musi odzyskać miejsce na stosie używane przez obiekty śmieci i ponownie udostępnić miejsce programowi.

Powyższe operacje są wykonywane przez algorytm Mark and Sweep w dwóch fazach:

  1. Zaznacz fazę
  2. Faza przemiatania

przeczytaj tutaj, aby uzyskać więcej informacji - Algorytm oznaczania i zamiatania

roottraveller
źródło
6

moduł odśmiecania pamięci oznacza, że ​​obiekty, które nie są już potrzebne programowi, są „śmieciami” i mogą zostać wyrzucone.

Nik
źródło
6

Garbage Collector jest częścią JRE, która zapewnia, że ​​obiekt, do którego nie ma odwołań, zostanie zwolniony z pamięci.
Zwykle działa, gdy zabraknie pamięci aplikacji. AFAIK zawiera wykres, który reprezentuje powiązania między obiektami, a izolowane obiekty mogą zostać zwolnione.
Aby zaoszczędzić wydajność, bieżące obiekty pogrupowane są w generacje, za każdym razem, gdy GC skanuje obiekt i stwierdza, że ​​nadal występuje odwołanie do jego liczby generacji zwiększonej o 1 (do jakiejś maksymalnej wartości maksymalnej, myślę, że 3 lub 4), a nowa generacja jest skanowana jako pierwsza (im najkrótszy obiekt w pamięci, tym bardziej prawdopodobne, że nie jest już potrzebny), więc nie wszystkie obiekty są skanowane przy każdym uruchomieniu GC.
przeczytaj to, aby uzyskać więcej informacji.

Itay Karo
źródło
@quantumSoup, czy jesteś w tym pozytywny? Uważam, że jakiś rodzaj zbierania śmieci (droższy) ma miejsce tylko wtedy, gdy sterta się zapełni.
Pablo Fernandez
2
@quantumSoup - to zależy od implementacji GC środowiska JRE. W wielu przypadkach GC nie działa stale. Zamiast tego jest uruchamiany, gdy aplikacja nie może przydzielić obiektu, ponieważ sterta jest pełna. Najnowsze maszyny JVM HotSpot zawierają równoległy GC, ale nie jest on domyślnie włączony.
Stephen C
Ta odpowiedź zbytnio koncentruje się na mechanizmie. Pytanie brzmiało „Co to jest śmieciarz”, a nie „Jak działa śmieciarz”
Billy ONeal
@quantum: zneutralizowaliśmy Twoje -1, ponieważ: Nauka, czyli do czego służy ta strona, prawda? Aby się uczyć, musisz popełniać błędy. Karanie błędów sprawia, że ​​ludzie się nie uczą. Mam nadzieję, że w tej kwestii możesz się zgodzić. A może popełniłeś błąd tutaj.
erikbwork
1
@erikb: Zgodnie z tą logiką nigdy nie byłoby głosów przeciw. A głosy przeciw są konieczne, aby wyeliminować stosunkowo słabe odpowiedzi. OP jest oczywiście początkującym, a specyficzne wewnętrzne działanie GC po prostu nie jest ważne dla zadanego pytania. Ponieważ ta odpowiedź nie odpowiada na zadane pytanie (odpowiada na inne), głosy przeciw są w pełni uzasadnione.
Billy ONeal
3

Moduł odśmiecania pamięci umożliwia komputerowi symulację komputera z nieskończoną pamięcią. Reszta to tylko mechanizm.

Robi to poprzez wykrywanie, kiedy fragmenty pamięci nie są już dostępne z twojego kodu i zwracanie tych fragmentów do darmowego magazynu.

EDYCJA: Tak, link jest przeznaczony dla C #, ale C # i Java są pod tym względem identyczne.

Billy ONeal
źródło
W SO jest właściwie pytanie o różnicę między java i C # GC: stackoverflow.com/questions/492703/c-vs-java-garbage-collector
NullUserException
3

Wiele osób uważa, że ​​zbieranie śmieci zbiera i odrzuca martwe obiekty.
W rzeczywistości zbieranie śmieci w Javie działa odwrotnie! Żywe obiekty są śledzone, a wszystko inne wyznaczane jako śmieci.

Gdy obiekt nie jest już używany, moduł wyrzucania elementów bezużytecznych odzyskuje pamięć bazową i ponownie wykorzystuje ją do przyszłej alokacji obiektu. Oznacza to, że nie ma jawnego usunięcia i żadna pamięć nie jest zwracana do systemu operacyjnego. Aby określić, które obiekty nie są już używane, maszyna JVM sporadycznie uruchamia tak zwany algorytm oznaczania i usuwania.

Sprawdź to, aby uzyskać więcej szczegółowych informacji: http://javabook.compuware.com/content/memory/how-garbage-collection-works.aspx

VdeX
źródło
1

Mówiąc najprościej, zrozumiałym nawet dla nieprogramisty, gdy program przetwarza dane, tworzy dla nich dane pośrednie i przestrzeń dyskową (zmienne, tablice, pewne metadane obiektów itp.).

Gdy dostęp do tych obiektów uzyskuje się za pośrednictwem funkcji lub powyżej określonego rozmiaru, są one przydzielane z centralnego stosu. Następnie, gdy nie są już potrzebne, należy je wyczyścić.

W Internecie jest kilka bardzo dobrych artykułów o tym, jak to działa, więc omówię tylko bardzo podstawową definicję.

GC jest w zasadzie funkcją, która to czyści. Aby to zrobić, usuwa wpisy tabeli, do których nie odwołują się żadne aktywne obiekty, skutecznie usuwając obiekty, a następnie kopiuje i kompaktuje pamięć. To trochę bardziej skomplikowane, ale masz pomysł.

Duży problem polega na tym, że niektóre części tego procesu często wymagają tymczasowego zatrzymania całej maszyny wirtualnej Java, aby mógł się odbyć, a cały ten proces jest bardzo obciążający procesor i przepustowość pamięci. Różne opcje GC i opcje strojenia dla każdego z nich mają na celu zrównoważenie tych różnych problemów z całym procesem GC.

Robert Wm Ruedisueli
źródło
0

Wyrzucanie elementów bezużytecznych w Javie (a także innych językach / platformach) to sposób na ponowne wykorzystanie pamięci z obiektów Java, które nie są już potrzebne, w środowisku wykonawczym Java (JRE). Mówiąc prościej, gdy środowisko JRE uruchamia się początkowo, prosi system operacyjny (O / S) o określoną ilość pamięci. Gdy środowisko JRE uruchamia aplikacje, wykorzystuje tę pamięć. Kiedy aplikacja korzysta z tej pamięci, pojawia się „Garbage Collector” środowiska JRE i odzyskuje tę pamięć do wykorzystania przez różne części istniejących aplikacji. „Garbage Collector” środowiska JRE jest zadaniem w tle, które jest zawsze uruchomione i próbuje wybierać czasy bezczynności systemu, aby przejść do operacji bezużytecznych.

Prawdziwą analogią byliby śmieciarze, którzy przychodzą do twojego domu i zbierają twoje nadające się do recyklingu śmieci ... w końcu zostaną ponownie wykorzystane w inny sposób przez ciebie i / lub innych ludzi.

Al Dass
źródło
0

Garbage collector może być postrzegany jako menedżer zliczania referencji. jeśli obiekt jest tworzony, a jego odniesienie jest przechowywane w zmiennej, jego liczba odwołań jest zwiększana o jeden. w trakcie wykonywania, jeśli tej zmiennej przypisano wartość NULL. liczba odwołań dla tego obiektu jest zmniejszana. tak więc bieżąca liczba odwołań dla obiektu wynosi 0. Teraz, gdy moduł wyrzucania elementów bezużytecznych jest wykonywany, sprawdza, czy istnieją obiekty z liczbą odwołań równą 0 i zwalnia przydzielone mu zasoby.

Wywołanie modułu odśmiecania pamięci jest kontrolowane przez zasady czyszczenia pamięci.

Możesz uzyskać trochę danych tutaj. http://www.oracle.com/technetwork/java/gc-tuning-5-138395.html

bala sreekanth
źródło
1
Liczenie referencji to kiepski sposób implementacji GC. Nie sądzę, aby jakakolwiek większa implementacja JVM tego używała.
NullUserException
0

Garbage collector jest składnikiem jvm.

Służy do zbierania śmieci, gdy procesor jest wolny.

Tutaj śmieci oznaczają nieużywane obiekty, które uruchamia się w tle głównego programu

do monitorowania statusu głównego programu.

Pulipati Prasadarao
źródło
0

Automatyczne czyszczenie pamięci to proces przeglądania pamięci sterty, identyfikowania, które obiekty są w użyciu, a które nie, oraz usuwania nieużywanych obiektów. Używany obiekt lub obiekt, do którego się odwołujesz, oznacza, że ​​jakaś część programu nadal utrzymuje wskaźnik do tego obiektu. Żadna część programu nie odwołuje się już do nieużywanego obiektu ani do obiektu bez odniesienia. Dzięki temu można odzyskać pamięć używaną przez obiekt bez odniesienia.

W języku programowania, takim jak C, przydzielanie i zwalnianie pamięci jest procesem ręcznym. W Javie proces zwalniania pamięci jest obsługiwany automatycznie przez moduł odśmiecania pamięci. Sprawdź link, aby lepiej zrozumieć. http://www.oracle.com/webfolder/technetwork/tutorials/obe/java/gc01/index.html

Shashank Shankaranand
źródło
0

Wyrzucanie elementów bezużytecznych odnosi się do procesu automatycznego zwalniania pamięci na stercie poprzez usuwanie obiektów, które nie są już osiągalne w programie. Sterta to pamięć określana jako magazyn wolny, reprezentująca dużą pulę nieużywanej pamięci przydzielonej do aplikacji Java.

Aamir M Meman
źródło
1
Nie używaj formatowania cytatów dla tekstu, który nie jest cytowany, a jeśli jest cytowany, musisz zacytować źródło.
Markiz Lorne
0

Podstawowe zasady czyszczenia pamięci polegają na znajdowaniu obiektów danych w programie, do których nie będzie można uzyskać dostępu w przyszłości, i odzyskiwaniu zasobów używanych przez te obiekty. https://en.wikipedia.org/wiki/Garbage_collection_%28computer_science%29

Zalety

1) Zapisuje błędy, które występują, gdy fragment pamięci jest zwalniany, gdy wciąż istnieją do niego wskaźniki, a jeden z tych wskaźników jest wyłuskiwany. https://en.wikipedia.org/wiki/Dangling_pointer

2) Podwójnie wolne błędy, które pojawiają się, gdy program próbuje zwolnić obszar pamięci, który został już zwolniony i być może został już ponownie przydzielony.

3) Zapobiega niektórym rodzajom wycieków pamięci, w których program nie zwalnia pamięci zajmowanej przez obiekty, które stały się nieosiągalne, co może prowadzić do wyczerpania pamięci.

Niedogodności

1) Zużycie dodatkowych zasobów, wpływ na wydajność, możliwe opóźnienia w wykonywaniu programu i niezgodność z ręcznym zarządzaniem zasobami. Wyrzucanie elementów bezużytecznych pochłania zasoby obliczeniowe przy podejmowaniu decyzji, która pamięć ma zostać zwolniona, nawet jeśli programista mógł już znać te informacje.

2) Moment, w którym śmieci są rzeczywiście zbierane, może być nieprzewidywalny, powodując przestoje (przerwy na zmianę / zwolnienie pamięci) rozproszone w trakcie sesji. Nieprzewidywalne opóźnienia mogą być niedopuszczalne w środowiskach czasu rzeczywistego, podczas przetwarzania transakcji lub w programach interaktywnych.


Samouczek Oracle http://www.oracle.com/webfolder/technetwork/tutorials/obe/java/gc01/index.html

Wyrzucanie elementów bezużytecznych to proces określający, które obiekty są używane, a które nie, oraz usuwając nieużywane obiekty.

W językach programowania, takich jak C, C ++, przydzielanie i zwalnianie pamięci jest procesem ręcznym.

int * array = new int[size];
processArray(array); //do some work.
delete array; //Free memory

Pierwszym krokiem w tym procesie jest znakowanie. Tutaj moduł odśmiecania pamięci identyfikuje, które fragmenty pamięci są używane, a które nie.

Krok 2a. Zwykłe usunięcie usuwa obiekty, do których nie istnieją odniesienia, pozostawiając obiekty, do których istnieją odniesienia, i wskaźniki do wolnego miejsca.

Aby poprawić wydajność, chcemy usunąć obiekty, do których nie istnieją odniesienia, a także kompaktować pozostałe obiekty, do których istnieją odniesienia. Chcemy trzymać razem obiekty, do których istnieją odniesienia, więc alokowanie nowej pamięci będzie szybsze.

Jak wspomniano wcześniej, oznaczanie i kompaktowanie wszystkich obiektów w JVM jest nieefektywne. Ponieważ coraz więcej obiektów jest alokowanych, lista obiektów rośnie i rośnie, prowadząc do coraz dłuższego czasu czyszczenia pamięci.

Kontynuuj czytanie tego samouczka, a dowiesz się, jak GC podejmuje to wyzwanie.

Krótko mówiąc, istnieją trzy regiony sterty, YoungGeneration dla obiektów o krótkim okresie życia, OldGeneration dla obiektów o długim okresie życia oraz PermanentGeneration dla obiektów, które żyją w czasie życia aplikacji, na przykład klas, bibliotek.

Yan Khonski
źródło
0

Ponieważ obiekty są dynamicznie przydzielane przez operatora new , możesz zapytać, w jaki sposób te obiekty są niszczone i jak zwalniana jest zajęta pamięć. W innych językach, takich jak C ++, musisz zwolnić ręcznie przydzielone obiekty dynamicznie za pomocą operatora delete. Java ma inne podejście; automatycznie obsługuje zwolnienie. Technika ta znana jest jako Garbage Collection .

Działa to w ten sposób: gdy nie ma odniesień do obiektu, zakłada się, że ten obiekt nie jest już potrzebny i można odzyskać pamięć zajmowaną przez obiekt. Nie jest konieczne jawne niszczenie obiektów, jak w C ++. Wyrzucanie elementów bezużytecznych występuje sporadycznie podczas wykonywania programu; Nie dzieje się tak po prostu z powodu jednego lub więcej obiektów, które nie są już używane. Ponadto kilka implementacji środowiska wykonawczego Java ma różne podejścia do czyszczenia pamięci, ale większość programistów nie musi się tym martwić podczas pisania programów.

Amarildo
źródło
-2

Automatyczne czyszczenie pamięci to proces, w którym JVM pozbywa się lub zachowuje określone punkty danych w pamięci, aby ostatecznie zwolnić miejsce dla uruchomionego programu. Pamięć jest najpierw wysyłana do pamięci sterty, czyli tam, gdzie moduł odśmiecania pamięci (GC) wykonuje swoją pracę, a następnie decyduje o zakończeniu działania lub zachowaniu. Java zakłada, że ​​programiście nie zawsze można ufać, więc kończy elementy, których uważa, że ​​nie potrzebuje.

Lopes_CP_2579
źródło