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.
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.
Odpowiedzi:
Ś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 String
s i File
s, 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 s
jest tworzony przy każdej iteracji for
pętli. Oznacza to, że w każdej iteracji przydzielana jest niewielka ilość pamięci, aby utworzyć String
obiekt.
Wracając do kodu, widzimy, że po wykonaniu pojedynczej iteracji w kolejnej iteracji String
obiekt, 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 malloc
ifree
. 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.
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 Object
staje 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)
System.gc()
nie zmusza GC do uruchomienia.
myObj
przed wywołaniem otherMethod
, ponieważ myObj
nie jest już dostępny w tym momencie.
System.gc()
, chodzi o to, aby mieć GC nie trzeba tego robić.
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 Heap
i Heap
dzielone 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.
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.
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()
.
public static void gc() {
Runtime.getRuntime().gc();
}
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:
przeczytaj tutaj, aby uzyskać więcej informacji - Algorytm oznaczania i zamiatania
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.
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.
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
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.
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.
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
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.
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
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.
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.
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.
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.