Dlaczego jest to zła praktyka, aby zadzwonić do systemu.gc ()?

Po odpowiedzianiu na pytanie, jak obiekty bez użycia siły w Javie (facet czyścił Hashmapę o pojemności 1,5 GB) za pomocą System.gc(), powiedziano mi, że ręczne wywoływanie System.gc() jest złą praktyką, ale komentarze nie były do końca przekonujące. Ponadto, nikt nie ośmielił się podnosić głosu, ani nie negować mojej odpowiedzi.

Powiedziano mi tam, że to zła praktyka, ale potem powiedziano mi również, że biegi śmieciarki Nie systematycznie zatrzymują już świata, i że może to również skutecznie być używane przez JVM tylko jako wskazówka, więc jestem trochę w stratę.

Rozumiem, że JVM zwykle wie lepiej niż ty, kiedy musi odzyskać pamięć. Rozumiem również, że martwienie się o kilka kilobajtów danych jest głupie. Rozumiem też, że nawet megabajty danych nie są tym, czym było kilka lat temu. Ale nadal 1,5 gigabajta? A Ty wiesz w pamięci wisi jakieś 1,5 GB danych; to nie jest tak, że to strzał w ciemności. Is System.gc() źle, czy jest jakiś moment, w którym wszystko staje się w porządku?

Więc pytanie jest rzeczywiście podwójne:

  • Dlaczego czy nie jest to zła praktyka, aby zadzwonić System.gc()? Czy to naprawdę tylko wskazówka dla JVM pod pewnymi implementacjami, Czy zawsze jest to pełny cykl zbierania? Czy naprawdę istnieją implementacje garbage collector, które mogą wykonywać swoją pracę bez zatrzymywania świata? Proszę rzucić trochę światła na różne twierdzenia, które ludzie poczynili w komentarzach do mojego ODPOWIEDŹ .
  • Gdzie jest próg? Czy to jest nigdy dobry pomysł, aby zadzwonić System.gc(), czy są czasy, kiedy to jest dopuszczalne? Jeśli tak, to jakie są te czasy?
Author: Community, 2010-03-10

13 answers

Powodem, dla którego każdy zawsze mówi, aby unikać System.gc() jest to, że jest to całkiem dobry wskaźnik zasadniczo złamanego kodu . Każdy kod, który zależy od niego pod względem poprawności, jest z pewnością zepsuty; każdy, który opiera się na nim pod względem wydajności, jest najprawdopodobniej zepsuty.

Nie wiesz, pod jakim śmieciarzem działasz. Z pewnością są takie, które nie "zatrzymują Świat" jak twierdzisz, ale niektóre JVM nie są tak inteligentne lub z różnych powodów (być może są na telefon? nie rób tego. Nie wiesz, co to zrobi. Poza tym, nie ma gwarancji, że nic nie zrobi. JVM może całkowicie zignorować Twoją prośbę.

Kombinacja "nie wiesz, co to zrobi", "nie wiesz, czy to w ogóle pomoże" i "nie powinieneś tak tego nazywać" jest powodem, dla którego ludzie tak stanowczo mówią, że generalnie nie powinieneś tego nazywać. Myślę, że jest to przypadek " jeśli musisz zapytać, czy powinieneś tego używać, możesz shouldn ' t "


Edytuj aby rozwiązać kilka problemów z drugiego wątku:

Po przeczytaniu wątku, który podlinkowałeś, jest jeszcze kilka rzeczy, na które chciałbym zwrócić uwagę. Po pierwsze, ktoś zasugerował, że wywołanie gc() może zwrócić pamięć do systemu. To z pewnością niekoniecznie prawda - sama sterta Javy rośnie niezależnie od alokacji Javy.

Jak w przypadku, JVM przechowuje pamięć (wiele dziesiątek megabajtów)i w razie potrzeby powiększa stertę. Niekoniecznie Zwróć tę pamięć do systemu nawet wtedy, gdy zwolnisz Obiekty Java; całkowicie bezpłatne jest trzymanie przydzielonej pamięci w celu wykorzystania jej do przyszłych alokacji Java.

Aby pokazać, że jest możliwe, że System.gc() nic nie robi, zobacz:

Http://bugs.sun.com/view_bug.do?bug_id=6668279

I w szczególności, że istnieje opcja maszyny wirtualnej -XX:DisableExplicitGC .

 224
Author: Steven Schlansker,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-12-12 10:55:00

Zostało już wyjaśnione, że wywołanie system.gc() Może nic nie robić, a każdy kod, który "potrzebuje" garbage collector do uruchomienia, jest zepsuty.

Jednak pragmatycznym powodem, że nazywanie System.gc() złą praktyką jest to, że jest to nieefektywne. A w najgorszym przypadku jest to strasznie nieefektywne! Pozwól mi wyjaśnić.

Typowy algorytm GC identyfikuje śmieci, przemierzając wszystkie obiekty nie-śmieci w stercie i wnioskując, że każdy obiekt nie odwiedzany musi bądź śmieciem. Na podstawie tego możemy modelować całkowitą pracę garbage collection składającą się z jednej części, która jest proporcjonalna do ilości danych na żywo, i drugiej części, która jest proporcjonalna do ilości śmieci; tj. work = (live * W1 + garbage * W2).

Teraz Załóżmy, że wykonujesz następujące czynności w aplikacji jednowątkowej.

System.gc(); System.gc();

Pierwsze wywołanie wykona (przewidujemy) (live * W1 + garbage * W2) pracę i pozbędzie się zaległych śmieci.

Drugie wezwanie zrobi (live* W1 + 0 * W2) pracę i nic nie odzyska. W innych słowa, które wykonaliśmy (live * W1) i nie osiągnęliśmy absolutnie niczego .

Możemy modelować wydajność kolektora jako ilość pracy potrzebną do zebrania jednostki śmieci, tj. efficiency = (live * W1 + garbage * W2) / garbage. Tak więc, aby GC było jak najbardziej wydajne, musimy zmaksymalizować wartość garbage kiedy uruchamiamy GC; tzn. poczekać, aż sterta będzie pełna. (A także, aby sterta tak duża, jak to możliwe. Ale to osobny temat.)

Jeśli aplikacja nie ingeruje (wywołując System.gc()), GC będzie czekać, aż sterta będzie pełna przed uruchomieniem, co skutkuje skutecznym zbieraniem śmieci1. Ale jeśli aplikacja zmusi GC do uruchomienia, jest szansa, że sterta nie będzie pełna, a w rezultacie śmieci będą zbierane nieefektywnie. A im częściej aplikacja wymusza GC, tym bardziej nieefektywna staje się GC.

Uwaga: powyższe Wyjaśnienie mówi o tym, że typowy współczesny GC dzieli stertę na "przestrzenie", GC może dynamicznie rozwijaj stertę, roboczy zestaw obiektów nie-śmieci może się różnić i tak dalej. Mimo to, ta sama podstawowa zasada dotyczy wszystkich prawdziwych śmieciarzy2. Nieefektywne jest zmuszanie GC do działania.


1 - tak działa kolektor "przepustowości". Współbieżne kolektory, takie jak CMS i G1, używają różnych kryteriów, aby zdecydować, kiedy uruchomić garbage collector.

2 - pomijam też pamięć Menedżery, które używają wyłącznie zliczania referencji, ale żadna obecna implementacja Javy nie używa tego podejścia ... nie bez powodu.

 134
Author: Stephen C,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-05-16 21:18:12

Wiele osób mówi ci, żebyś tego nie robił. Nie zgadzam się. Jeśli po dużym procesie ładowania, takim jak ładowanie poziomu, uważasz, że:

  1. masz wiele obiektów, które są nieosiągalne i mogą nie być GC ' ed. oraz
  2. myślisz, że użytkownik może znieść małe spowolnienie w tym momencie
Nie ma nic złego w wywołaniu systemu.gc(). Patrzę na to jak na słowo kluczowe c / C++ inline. To tylko wskazówka dla gc, że ty, deweloper, zdecydowałeś, że czas / wydajność nie jest tak ważna jak zwykle i że część z nich może być wykorzystana do odzyskiwania pamięci.

Rada, aby nie polegać na tym, że nic nie robi, jest poprawna. Nie polegaj na tym, że działa, ale podpowiedź, że teraz jest akceptowalny czas na zebranie, jest całkowicie w porządku. Wolałbym marnować czas w punkcie kodu, w którym nie ma to znaczenia (ekran ładowania) niż wtedy, gdy użytkownik aktywnie wchodzi w interakcję z programem (jak na poziomie gry.)

Jest jeden raz, kiedy będę Siła kolekcja: gdy próbuje dowiedzieć się, czy dany obiekt wycieka (albo kod natywny lub duża, złożona interakcja zwrotna. Oh I każdy komponent UI, który choć spojrzy na Matlab.) to nie powinno być używane w kodzie produkcyjnym.

 42
Author: KitsuneYMG,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-10-10 13:48:53

Ludzie wykonują dobrą robotę wyjaśniając, dlaczego nie używać, więc powiem ci kilka sytuacji, w których powinieneś go używać:

(poniższe uwagi dotyczą hotspota działającego pod Linuksem z CMS collector, gdzie czuję się pewnie mówiąc, że System.gc() w rzeczywistości zawsze wywołuje pełne śmieci).

  1. Po początkowej pracy uruchamiania aplikacji, może być straszny stan zużycia pamięci. Połowa twojego pokolenia może być pełna śmieci, oznacza to, że jesteś o wiele bliżej swojego pierwszego CMS. W aplikacjach, gdzie to ma znaczenie, nie jest złym pomysłem, aby zadzwonić do systemu.gc (), aby "zresetować" stertę do stanu początkowego danych na żywo.

  2. Podobnie jak #1, jeśli uważnie monitorujesz użycie sterty, chcesz dokładnie odczytać zużycie pamięci bazowej. Jeśli pierwsze 2 minuty uptime aplikacji to inicjalizacja, Twoje dane będą pomieszane, chyba że zmusisz (ahem... "suggest").

  3. Możesz mieć aplikację, która jest zaprojektowana, aby nigdy nie promować niczego do pokolenia najemnego, gdy jest uruchomiona. Ale może trzeba zainicjować pewne dane z góry, które nie są tak ogromne, aby automatycznie przenieść się do pokolenia etatu. Chyba, że zadzwonisz do systemu.gc () po skonfigurowaniu, Twoje dane mogą zasiąść w nowej generacji, aż przyjdzie czas na awans. Nagle twoje super-duper low-latency, low-GC aplikacja zostaje uderzona ogromną (stosunkowo rzecz biorąc, oczywiście) karą opóźnienia za promowanie tych obiektów podczas normalnej pracy.

  4. Czasami warto mieć System.wywołanie gc dostępne w aplikacji produkcyjnej w celu sprawdzenia istnienia wycieku pamięci. Jeśli wiesz, że zestaw danych na żywo w czasie X powinien istnieć w pewnym stosunku do zestawu danych na żywo w czasie Y, wtedy może być przydatne Wywołanie Systemu.gc () a czas X i czas Y i porównaj pamięć użycie.

 26
Author: JT.,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-02-09 14:13:47

Wydajność GC opiera się na wielu heurystykach. Na przykład, powszechną heurystyką jest to, że dostęp zapisu do obiektów występuje zwykle na obiektach, które zostały utworzone niedawno. Innym jest to, że wiele obiektów jest bardzo krótkotrwałych (niektóre obiekty będą używane przez długi czas, ale wiele z nich zostanie odrzuconych kilka mikrosekund po ich utworzeniu).

Wywołanie System.gc() jest jak kopnięcie GC. Oznacza to: "wszystkie te starannie dostrojone parametry, te inteligentne organizacje, cały wysiłek, który właśnie włożyłeś do przydzielania i zarządzania obiektami, tak aby wszystko poszło gładko, cóż, po prostu rzuć wszystko i zacznij od zera". To Może poprawić wydajność, ale w większości przypadków po prostu obniża wydajność.

Aby używać System.gc() niezawodnie (*) musisz wiedzieć, jak działa GC we wszystkich jego drobnych szczegółach. Takie szczegóły zmieniają się nieco, jeśli używasz JVM od innego dostawcy, lub następnej wersji od tego samego dostawcy, lub tego samego JVM, ale z nieco innymi opcje wiersza poleceń. Tak więc rzadko jest to dobry pomysł, chyba że chcesz rozwiązać konkretny problem, w którym kontrolujesz wszystkie te parametry. Stąd pojęcie "złej praktyki": to nie jest zabronione, metoda istnieje, ale rzadko się opłaca.

(*) mówię tu o efektywności. System.gc() nigdy nie złamie poprawnego programu Java. Nie będzie też wywoływać dodatkowej pamięci, której JVM nie mógłby uzyskać w inny sposób: przed rzuceniem OutOfMemoryError, JVM wykonuje zadanie System.gc(), nawet jeśli w ostateczności.

 9
Author: Thomas Pornin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-03-10 16:25:08

Sometimes (not Frequency!) naprawdę wiesz więcej o przeszłym, obecnym i przyszłym wykorzystaniu pamięci, niż czas wykonywania. Nie zdarza się to zbyt często i twierdziłbym, że nigdy w aplikacji internetowej, podczas gdy zwykłe strony są serwowane.

Wiele lat temu pracowałem nad generatorem raportów, że

  • miał pojedynczy wątek
  • odczytaj "żądanie zgłoszenia" z kolejki
  • załadował dane potrzebne do raportu z bazy danych
  • wygenerował raport i wysłałem e-mailem.
  • Powtarzane na zawsze, śpiące, gdy nie było żadnych zaległych próśb. [7]}nie wykorzystywał ponownie żadnych danych między raportami i nie realizował żadnych transakcji.

Po pierwsze, ponieważ nie był to czas rzeczywisty i użytkownicy oczekiwali oczekiwania na raport, opóźnienie podczas biegu GC nie było problemem, ale musieliśmy tworzyć raporty w tempie szybszym niż oczekiwano.

Patrząc na powyższy zarys procesu, jest jasne, że.

  • wiemy tuż po wysłaniu raportu będzie bardzo mało żywych obiektów, ponieważ następne żądanie nie zaczęło być jeszcze przetwarzane.
  • powszechnie wiadomo, że koszt uruchomienia cyklu zbierania śmieci zależy od liczby żywych obiektów, ilość śmieci ma niewielki wpływ na koszt uruchomienia GC.
  • że gdy kolejka jest pusta nie ma nic lepszego do roboty to Uruchom GC.

Dlatego oczywiście warto było zrobić GC run ilekroć Kolejka żądań była pusta; nie było w tym żadnych minusów.

Może warto zrobić GC run po każdym raporcie jest wysyłane e-mailem, ponieważ wiemy, że jest to dobry czas na GC run. Jednak gdyby komputer miał wystarczającą ilość pamięci ram, lepsze wyniki można uzyskać opóźniając uruchomienie GC.

To zachowanie zostało skonfigurowane na podstawie instalacji, dla niektórych klientów umożliwiających wymuszone GC po każdym raporcie znacznie przyspieszyło zwiększenie ochrony raportów. (Oczekuję tego było ze względu na niską pamięć na ich serwerze i to działa wiele innych procesów, więc stąd dobrze czas zmuszony GC zmniejszone stronicowania.)

Nigdy nie wykryliśmy instalacji, która nie korzystała z wymuszonego uruchomienia GC za każdym razem, gdy kolejka robocza była pusta.

Ale, żeby było jasne, powyższe nie jest częstym przypadkiem.

 5
Author: Ian Ringrose,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-09-29 13:27:27

Jest to bardzo uciążliwe pytanie i czuję, że wielu jest przeciwnych Javie pomimo tego, jak przydatny jest język.

Fakt, że nie można ufać "systemowi.gc "robić cokolwiek jest niesamowicie zniechęcające i można łatwo przywołać" strach, niepewność, zwątpienie " czuć do języka.

W wielu przypadkach miło jest radzić sobie ze skokami pamięci, które powodujesz celowo przed wystąpieniem ważnego wydarzenia, co sprawiłoby, że użytkownicy pomyślą, że twój program jest zły zaprojektowany/nie reaguje.

Posiadanie zdolności do kontrolowania zbierania śmieci byłoby bardzo świetnym narzędziem edukacyjnym, z kolei poprawiając ludziom zrozumienie, jak działa wywóz śmieci i jak sprawić, by programy wykorzystywały jego domyślne zachowanie, jak również kontrolowane zachowanie.

Pozwolę sobie przejrzeć argumenty tego wątku.

  1. jest nieefektywny:

Często program może nic nie robić i wiesz, że nic nie robi, ponieważ sposób, w jaki został zaprojektowany. Na przykład, może to być robi jakiś rodzaj długiego oczekiwania z dużym oknie wiadomości oczekiwania, a na końcu może równie dobrze dodać wezwanie do zbierania śmieci, ponieważ czas do uruchomienia zajmie naprawdę mały ułamek czasu długiego oczekiwania, ale pozwoli uniknąć gc od działania w środku ważniejszej operacji.

  1. jest to zawsze zła praktyka i wskazuje na złamany kod.

Nie zgadzam się, nie ma znaczenia jaki Śmieciarz masz. Jego zadaniem jest namierz śmieci i wyczyść je.

Wywołując GC w czasach, w których użycie jest mniej krytyczne, zmniejszasz szanse na jego działanie, gdy twoje życie opiera się na uruchomieniu określonego kodu, ale zamiast tego decyduje się on zbierać śmieci.

Jasne, może nie zachowywać się tak, jak chcesz lub oczekujesz, ale kiedy chcesz go nazwać, wiesz, że nic się nie dzieje,a użytkownik jest gotów tolerować spowolnienie / przestój. Jeśli System.gc działa, świetnie! Jeśli nie, to przynajmniej próbowałeś. Po prostu nie ma down side, chyba że garbage collector ma nieodłączne skutki uboczne, które robią coś straszliwie nieoczekiwanego do tego, jak powinien zachowywać się garbage collector, jeśli zostanie wywołany ręcznie, a to samo powoduje nieufność.

  1. nie jest to powszechny przypadek użycia:

Jest to przypadek użycia, który nie może być osiągnięty w sposób niezawodny, ale może być, jeśli system został zaprojektowany w ten sposób. To jak robienie sygnalizacji świetlnej i robienie tego tak, aby niektóre/wszystkie przyciski świateł nic nie robiły, sprawia, że pytanie dlaczego przycisk jest tam na początek, javascript nie ma funkcji garbage collection więc nie analizujemy go tak bardzo dla niego.

  1. spec mówi, że System.gc () jest wskazówką, że GC powinno działać, a maszyna wirtualna może ją zignorować.

Co to jest "podpowiedź"? co to jest "ignoruj"? komputer nie może po prostu przyjmować podpowiedzi lub ignorować czegoś, istnieją ścisłe ścieżki zachowań, które mogą być dynamiczne, które kierują się intencją systemu. Prawidłowa odpowiedź byłaby uwzględnij to, co w rzeczywistości robi garbage collector, na poziomie implementacji, co powoduje, że nie wykonuje on zbierania, gdy o to poprosisz. Czy funkcja jest po prostu nop? Czy są jakieś warunki, które muszę spełnić? Jakie są te warunki?

W obecnej sytuacji, Java GC często wydaje się potworem, któremu po prostu nie ufasz. Nie wiesz, kiedy to nadejdzie, czy odejdzie, nie wiesz, co to zrobi, jak to zrobi. Mogę sobie wyobrazić, że niektórzy eksperci mają lepsze pojęcie o tym, jak ich zbieranie śmieci działa na podstawie instrukcji, ale zdecydowana większość po prostu ma nadzieję, że "po prostu działa", a zaufanie do nieprzezroczystego algorytmu do pracy dla Ciebie jest frustrujące.

Istnieje duża luka pomiędzy czytaniem o czymś lub byciem czegoś uczonym, a faktycznym widzeniem jego implementacji, różnic między systemami, a możliwością zabawy z tym bez konieczności patrzenia na kod źródłowy. Stwarza to pewność siebie i poczucie opanowanie / zrozumienie / Kontrola.

Podsumowując, istnieje nieodłączny problem z odpowiedziami "ta funkcja może nic nie robić, i nie będę wchodzić w szczegóły, jak powiedzieć, kiedy coś robi, a kiedy nie i dlaczego nie robi lub nie robi, często sugerując, że jest to po prostu sprzeczne z filozofią, nawet jeśli intencja za tym stoi jest rozsądna".

Może być w porządku, aby Java GC zachowywała się tak, jak robi, lub może nie, ale aby to zrozumieć, trudno jest naprawdę podążaj za tym, w którym kierunku iść, aby uzyskać kompleksowy przegląd tego, co możesz zaufać GC, aby zrobić, a nie robić, więc zbyt łatwo jest po prostu nie ufać językowi, ponieważ celem języka jest kontrolowanie zachowań do filozoficznego stopnia(łatwo jest programiście, zwłaszcza początkującym, wpaść w kryzys egzystencjalny z powodu pewnych zachowań systemowych/językowych), jesteś w stanie tolerować (a jeśli nie możesz, po prostu nie będziesz używać języka, dopóki nie będziesz musiał), i więcej rzeczy, które możesz zrobić, to nie można kontrolować z nieznanego powodu, dlaczego nie można kontrolować ich jest z natury szkodliwe.

 5
Author: Dmitry,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-06-30 00:14:09

Może piszę gówniany kod, ale zdałem sobie sprawę, że klikanie ikony kosza na eclipse i netbeans IDEs jest 'dobrą praktyką'.

 2
Author: Ryan Fernandes,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-03-10 09:09:53

Po pierwsze, istnieje różnica między specyfiką a rzeczywistością. Spec mówi, że System.gc () jest wskazówką, że GC powinno działać, a maszyna wirtualna może ją zignorować. W rzeczywistości maszyna wirtualna nigdy nie zignoruje połączenia z systemem.gc().

Wywołanie GC wiąże się z nietrywialnym obciążeniem połączenia i jeśli zrobisz to w jakimś przypadkowym momencie, prawdopodobnie nie zobaczysz żadnej nagrody za swoje wysiłki. Z drugiej strony, naturalnie wywołana windykacja jest bardzo prawdopodobne, aby odzyskać koszty wezwania. Jeśli masz informacje, które wskazują, że GC powinien być uruchomiony, niż można wykonać połączenie do systemu.gc () i powinieneś zobaczyć korzyści. Jednak z mojego doświadczenia wynika, że dzieje się to tylko w kilku przypadkach krawędzi, ponieważ jest bardzo mało prawdopodobne, że będziesz miał wystarczająco dużo informacji, aby zrozumieć, czy i kiedy System.należy wywołać GC ().

Jeden z przykładów wymienionych tutaj, uderzanie w śmietnik w IDE. Jeśli idziesz na spotkanie, dlaczego nie uderzyć. Napowietrzne nie wpłynie na Ciebie i sterty mogą być czyszczone kiedy wrócisz. Zrób to w systemie produkcyjnym, a częste rozmowy o zbieraniu doprowadzą go do końca! Nawet okazjonalne połączenia, takie jak te wykonane przez RMI, mogą zakłócać wydajność.

 2
Author: Kirk,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-09-02 10:29:01

Tak, system wywołujący.gc() nie gwarantuje, że będzie działać, jest to żądanie do JVM, które może zostać zignorowane. Z docs:

Wywołanie metody gc sugeruje, że wirtualna maszyna Javy przeznacza wysiłek na recykling nieużywanych obiektów

To prawie zawsze zły pomysł, aby go nazwać, ponieważ automatyczne zarządzanie pamięcią zwykle wie lepiej niż ty, kiedy do gc. Zrobi to, gdy jego wewnętrzna Pula wolnej pamięci jest niska lub jeśli system operacyjny zażąda pewnej pamięci oddałem.

Może być dopuszczalne Wywołanie Systemu.gc () jeśli wiesz że to pomaga. Mam przez to na myśli, że dokładnie przetestowałeś i zmierzyłeś zachowanie obu scenariuszy na platformie wdrożeniowej i możesz pokazać, że to pomaga. Należy jednak pamiętać, że GC nie jest łatwo przewidywalne - może pomóc na jednym biegu i boli na drugim.

 1
Author: tom,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-03-10 02:34:37

Z mojego doświadczenia, korzystanie z systemu.gc () jest właściwie specyficzną dla platformy formą optymalizacji (gdzie "platforma" jest połączeniem architektury sprzętowej, systemu operacyjnego, wersji JVM i możliwej większej liczby parametrów runtime, takich jak Dostępna pamięć RAM), ponieważ jej zachowanie, chociaż z grubsza przewidywalne na określonej platformie, może (i będzie) znacznie się różnić między platformami.

Tak, istnieją sytuacje, w których Systemgc () poprawi (postrzeganą) wydajność. Na przykład, jeśli opóźnienia są tolerowane w niektórych częściach aplikacji, ale nie w innych (przykład gry przytoczony powyżej, gdzie chcesz, aby GC stało się na początku poziomu, a nie podczas poziomu).

Jednak to, czy pomoże, czy zaszkodzi (lub nie zrobi nic), jest wysoce zależne od platformy (jak zdefiniowano powyżej).

Więc myślę, że jest to ważne jako ostateczność optymalizacji platformy specyficznej (tj. jeśli inne optymalizacje wydajności nie są wystarczające). Ale nigdy nie powinieneś tego nazywać tylko dlatego, że wierzysz, że może pomocy (bez konkretnych benchmarków), bo są szanse, że nie będzie.

 0
Author: sleske,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-09-17 10:56:02
  1. Ponieważ obiekty są przydzielane dynamicznie za pomocą nowego operatora,
    być może zastanawiasz się, w jaki sposób takie obiekty są niszczone i ich
    pamięć udostępniona do późniejszej realokacji.

  2. W niektórych językach, np. C++, dynamicznie przydzielane obiekty muszą być ręcznie zwalniane za pomocą operatora delete.

  3. Java ma inne podejście; obsługuje dealokację dla Ciebie automatycznie.
  4. technika, która tego dokonuje, nazywa się garbage kolekcja. Działa to tak: gdy nie ma odniesień do obiektu, zakłada się, że obiekt nie jest już potrzebny, a pamięć zajmowana przez obiekt może zostać odzyskana. Nie ma wyraźnej potrzeby niszczenia obiektów jak w C++.
  5. zbiórka śmieci występuje tylko sporadycznie (jeśli w ogóle) podczas wykonanie Twojego programu.
  6. nie nastąpi po prostu dlatego, że istnieje jeden lub więcej obiektów, które są nie jest już używany.
  7. Ponadto różne implementacje Javy będą take różne podejścia do zbierania śmieci, ale w większości przypadków, można nie trzeba o tym myśleć podczas pisania programów.
 0
Author: Tanmay Delhikar,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-07-22 18:31:03

Moje 2 grosze: Ładuję jakieś animacje do aktywności i je odtwarzam. Ładuję, odtwarzam, a następnie ustawiam tło imageview NA null, po jednym na raz. Jeśli wyjdę z aktywności, a następnie wrócę szybko, po 3 lub 4 razy zaangażowana pamięć rośnie zbyt dużo, dopóki nie dostanę wyjątku poza pamięcią.

Wywołując garbage collector jawnie po ustawieniu tła imageview NA null, widzę na Eclipse logcat, że pamięć jest wystarczająco wolna - a w moim przypadku GC jest faktycznie uruchomiony - i nie rozumiem, że aplikacja przestała działać.

To oczywiste, że system może zdecydować się na odroczenie wykonania gc, ale jeśli wiesz mniej więcej, jak działa gc, możesz zaufać w przypadku takim jak mój, który zostanie wywołany tak szybko, jak to możliwe, ponieważ system zauważa, że pamięć używana rośnie i aplikacja ma zamiar poprosić o więcej do systemu. Myślę, że to działa jak kontenery biblioteki C++ std: dostajesz trochę pamięci startowej i za każdym razem, gdy jej nie wystarczy, podwaja się.

Mówiąc, że jeśli trzeba to nazwać to z powodu zepsutego lub złego kodu jest nieuzasadnionym dogmatycznym sposobem odpowiedzi dla mnie: expecially jeśli możesz programować w języku z całkowitym ręcznym zarządzaniem pamięcią, takim jak C++ i musisz zmierzyć się z limitem zasobów na urządzeniu mobilnym z językiem takim jak java zamiast tego, bez szansy na ręczne zwolnienie pamięci, szybko możesz pomyśleć o wielu sytuacjach, w których konieczne jest jawne wywołanie gc, expecially gdzie masz śledzenie gc, a nie odniesienie liczące jeden, możesz użyć kodu jest czysty i dobrze zrobiony.

 -1
Author: Black Imp,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-03-30 04:44:22