Jak zmusić garbage collectora do działania?


147

Dziennikarz zapytał mnie o to dzisiaj ... czy jest na to odpowiedź?


3
To pytanie zawiera dobre informacje o tym, dlaczego nie powinieneś tego robić: stackoverflow.com/questions/118633/…
Hans Olsson

1
dlaczego tak mówisz
Andrew Collins,

1
@Jason - Może ankieter nie chciał usłyszeć rozwiązania, a raczej zdobyć wiedzę i argumenty Andrzeja przeciwko zrobieniu tego, wtedy to pytanie mogłoby mieć sens.
martinstoeckli

2
@martinstoeckli To wciąż straszne pytanie. Ktoś, kto ma wiedzę podczas stresującego wywiadu, nie zdawałby sobie sprawy, że jest to podchwytliwe pytanie, ani nie pomyślałby o dostarczeniu dodatkowych informacji. Wtedy pytanie nie pomaga ankieterowi w rozróżnieniu między kimś, kto ma wiedzę, a kimś bez niej. Więc pytanie jest nadal straszne.
James,

2
„Kiedy wymuszasz zbieranie śmieci?” brzmi dla mnie jak dobre pytanie do wywiadu („Jak”: nie za bardzo). Początkujący: nie wiem. Średniozaawansowany: nigdy. Ekspert: kiedy piszesz test na wycieki pamięci.
mikebridge

Odpowiedzi:


188

System.GC.Collect()wymusza działanie garbage collectora. Nie jest to zalecane, ale można z niego skorzystać w przypadku zaistnienia sytuacji.


17
Dlaczego nie jest to zalecane?
Luke T. O'Brien

5
GC.Collect () jest drogie w obsłudze. Robienie tego więcej niż to konieczne jest niewskazane. Kod określający, kiedy należy go wywołać, jest dobrze napisany. Zwykle należy zbierać się samodzielnie tylko w specjalistycznych przypadkach skrajnych. stackoverflow.com/a/21961777/2710988
Brandon Barkley

186

Nie jest zalecane jawne wywoływanie gc, ale jeśli wywołujesz

GC.Collect();
GC.WaitForPendingFinalizers();

Wywoła GC jawnie w całym kodzie, nie zapomnij wywołać GC.WaitForPendingFinalizers();po GC.Collect().


14
WaitForPendingFinalizersniekoniecznie zapewnia „lepszą wydajność”: po prostu blokuje, dopóki wszystkie obiekty w kolejce finalizacji nie zostaną sfinalizowane (obiekty, które mogły zostać tam umieszczone przez poprzednie wywołanie Collect). Jeśli chcesz mieć szansę na zebranie tych obiektów, po wywołaniu potrzebujesz kolejnego połączenia . Collect WaitForPendingFinalizers
LukeH

2
Ponieważ jednym z niewielu dobrych powodów, dla których warto zadzwonić do gc.Collect, jest ostatnia próba uwolnienia zasobów, które nie zostały prawidłowo usunięte, WaitForPendingFinalizers wydaje się koniecznym krokiem. Nie jestem jednak pewien, jaka byłaby najlepsza praktyka, aby uniknąć nadmiernego wywoływania gc.Collect w takich przypadkach. Przy okazji, zastanawiam się, czy jest jakiś techniczny powód, dla którego gc.Collect „ma” promować pokolenia? Wydawałoby się, że bardziej przydatne byłoby pozostawienie pokoleń na miejscu, chyba że w jednym z nich przydzielono wystarczająco dużo rzeczy, aby uzasadnić jego rozwój.
supercat

2
Uwaga dla początkujących w C # (takich jak ja): wywołanie siły GC nie gwarantuje, że jakiś konkretny nieużywany obiekt zostanie usunięty z pamięci. (jednym ze sposobów jest użycie „using instrukcji” ( msdn.microsoft.com/ru-ru/library/yh598w02(v=vs.80).aspx ))
user1234567

Dlaczego dzwonienie powinno być ważne WaitForPendingFinalizers?
Christian

19
GC.Collect() 

z MDSN ,

Użyj tej metody, aby spróbować odzyskać całą niedostępną pamięć.

Wszystkie obiekty, niezależnie od tego, jak długo były w pamięci, są brane pod uwagę do kolekcji; Jednak obiekty, do których istnieją odwołania w kodzie zarządzanym, nie są zbierane. Użyj tej metody, aby wymusić na systemie próbę odzyskania maksymalnej ilości dostępnej pamięci.



12

GC.Collect();

Pamiętaj jednak, że Garbage Collector może nie zawsze wyczyścić to, czego oczekujesz ...


5
Co przez to rozumiesz? Co mogło to nieoczekiwanie wyczyścić?
Voldemort

5
@Voldemort - nieoczekiwanie niczego nie wyczyści. Ale może nie wyczyścić wszystkiego, czego od niego oczekujesz.
Justin Niessner

6

Nie chcesz zmuszać modułu odśmiecania pamięci do działania.

Jeśli jednak kiedykolwiek to zrobiłeś (jako ćwiczenie czysto akademickie):

GC.Collect()

4
Wolę odpowiedź @ Karthik, mogą wystąpić sytuacje, w których aplikacja powinna zgodnie z prawem wywołać GC.Collect (). Jednak bardzo rzadko.
Henk Holterman

2
Załóżmy, że masz szereg słabych odniesień i chcesz sprawdzić, czy istnieją jakieś „aktywne” odniesienia. Przed sprawdzeniem warto wywołać GC.Collect (). Tylko mówię.
Rich Ehmer

1
Negocjowano, ponieważ oświadczenie otwierające jest niezgodne ze stanem faktycznym; Tak, chcę zmusić zbieracz śmieci do działania.
Syndog,

5

Myślę, że .Net Framework robi to automatycznie, ale na wszelki wypadek. Najpierw upewnij się, że wybrałeś to, co chcesz wymazać, a następnie zadzwoń do garbage collectora:

randomClass object1 = new randomClass
...
...
// Give a null value to the code you want to delete
object1 = null;
// Then call the garbage collector to erase what you gave the null value
GC.Collect();

Myślę, że to wszystko… Mam nadzieję, że komuś pomogę.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.