2012-03-02 14 views
9

Powiel możliwe:
Forcing Garbage Collection in Java?Czy mogę wymuszać odbiór śmieci w Javie?

można wymusić zbierania śmieci w Javie za pomocą wszelkich środków?

System.gc() to tylko sugestia. To jest bezużyteczne.

Kiedy wiem na pewno, że niektóre zasoby nie będą więcej używane, dlaczego nie mogę ich wymusić?

Podobnie jak delete() w C++ i free() w C?

Gdy istnieje wiele zasobów, których nie można ponownie wykorzystać, może to naprawdę wyssać wydajność. Wszystko, co możemy zrobić, to uśpić().

Wszelkie rozwiązania? Dzięki

Odpowiedz

12

Nie, System.gc() jest tak blisko, jak można dostać. Java nie jest C lub C++, JVM zarządza pamięcią dla ciebie, więc nie masz tego rodzaju drobnoziarnistej kontroli. Jeśli ustawisz obiekty, których już nie używasz, lub usuniesz wszystkie odniesienia, zostaną one oczyszczone. A GC jest całkiem sprytny, więc powinien troszczyć się o ciebie.

To powiedziawszy, jeśli jesteś na unixowym polu i wymuszasz zrzut wątku (kill -3), to prawie wymusisz zbieranie śmieci.

+4

+1 dla "GC jest inteligentny." (Jest to naprawdę inteligentne i bardzo rzadko jest to prawdziwa przyczyna wąskich gardeł wydajności). –

+0

@Michael Co to jest w systemie Unix i wymuszaniu zrzutu wątku? W jaki sposób ta gwarancja wywóz śmieci? – Geek

+1

@Geek - Ilekroć JVM wykonuje zrzut wątku, wstrzymuje się do zbierania śmieci. Robi to w każdym systemie operacyjnym, mówiąc szczerze, jest to po prostu najłatwiejsze do zrobienia w systemie Unix/Linux ze względu na dostępność "zabicia". Jeśli jesteś w systemie Windows z Cygwin, wierzę, że możesz osiągnąć to samo. – Michael

1

Nie ma możliwości wyraźnego polecenia JVM zbierania śmieci. Jest to wykonywane tylko wtedy, gdy system potrzebuje zasobów.

tylko dwa działania Jestem świadomy potencjalnie dostać biegu GC są następujące:

  1. Jak wspomniano, próba „sugerują, że” GC teraz byłby dobry moment, by o nazwie System. gc().
  2. Ustaw wszystkie referencje, których nie używasz, do odwołania pustego, aby elementy mogły być kolekcjonowane.

W moim drugim punkcie, patrz odpowiedź tutaj: Garbage collector in java - set an object null. W gruncie rzeczy, jeśli nie stworzysz obiektów, których nie potrzebujesz do zbierania śmieci (tracąc referencje), nie ma powodu, aby mógł uruchomić się garbage collector, ponieważ nie zna on żadnych dostępnych śmieci.

Ponadto, ważne jest, aby zastanowić się, dlaczego/jak te obiekty w pamięci mają wpływ na wydajność:

  • Czy otrzymujesz wiele OutOfMemoryExceptions? Można to rozwiązać za pomocą punktu # 2 i zwiększając dostępne miejsce sterty dla maszyny JVM.
  • Czy wykonałeś pomiary, aby zobaczyć, że więcej obiektów w przydzielonej przestrzeni JVM ma wpływ na wydajność? Ustalenie, kiedy można wcześniej odwołać się do obiektów, może pomóc w zmniejszeniu tych problemów.
5

Ty nie należy próbować zmusić GC - jeśli brakować pamięci to masz przeciek pamięci gdzieś. Wymuszenie GC w tym momencie nie pomoże, ponieważ jeśli będziesz trzymał odnośnik do obiektu, to nadal nie będzie on zbiorem śmieci.

To, co musisz zrobić, to rozwiązać prawdziwy problem i upewnić się, że nie przechowujesz odniesień do obiektów, których już nie używasz.

Niektóre wspólne winowajcy:

  • Trzymając wiele odniesień w dużym wykres obiektu, który nigdy się nie wyjaśni. Ustawiaj odwołania do wartości NULL, gdy ich już nie potrzebujesz, lub jeszcze lepiej uprość wykres obiektów, aby nie potrzebować wszystkich dodatkowych odwołań długoterminowych.
  • Buforowanie obiektów w hashmapie lub czymś podobnym, które z czasem rośnie. Przestań to robić, lub użyj czegoś takiego jak Google CacheBuilder, aby utworzyć odpowiednią miękką pamięć podręczną odniesienia.
  • Użycie String.intern() nadmiernie na dużej liczbie różnych ciągów znaków w czasie.
  • Referencje o większym zakresie niż są potrzebne. Czy używasz zmiennej instancji, na przykład gdy jest to zmienna lokalna?
+0

Dobre sugestie. Będę musiał. Dzięki – Jacob

+1

Istnieją powody, aby wymusić GC. Najwyraźniej, jeśli masz zamiar wprowadzić wrażliwy na opóźnienia fragment kodu, który współdziała z rzeczywistym światem, i chciałbyś zminimalizować szansę, że GC wstrzyma się na "dużą" kolekcję. Oczywiście, jeśli opóźnienie jest naprawdę ważne, Java nie jest najlepszym językiem dla tego problemu, ale czasami znajdujesz się w miejscu, w którym tego rodzaju błąd nie może zostać cofnięty. –

+0

Właśnie debugowałem aplikację, gdy pamięć rosła w sposób niekontrolowany, bez widocznej przyczyny, i szybko zabrakło 150 GB. Dodanie System.gc() w strategicznych miejscach naprawiło go i zatrzymało poniżej 35GB. Aplikacja wymaga dużej ilości pamięci i jest bardzo równoległa. GC nie jest magicznym pociskiem i jest zoptymalizowany pod kątem typowych przypadków użycia. Czasami konieczne jest podanie wskazówki gc() nawet wtedy, gdy wszystkie odniesienia są wydane/poza zasięgiem. – morfizm

Powiązane problemy