Як змусити запустити збирач сміття?


153

Сьогодні інтерв'юер запитав мене про це ... чи є відповідь?


4
У цьому питанні є хороша інформація про те, чому ви не повинні цього робити: stackoverflow.com/questions/118633/…
Ганс Ольссон,

1
чому ти так розповідаєш
Ендрю Коллінз

2
@ Джейсон - Можливо, інтерв'юер не хотів почути рішення, скоріше отримати знання та аргументи Ендрю проти того, щоб це робити, тоді це питання могло б ефективно мати сенс.
martinstoeckli

2
@martinstoeckli Це все ще жахливе питання. Хтось із знаннями під час напруженого інтерв’ю не зрозуміє, що це хитромудре питання, або не думає надати додаткову інформацію. Тоді запитання не допомагає інтерв'юеру розрізнити когось із знанням чи когось без нього. Тож питання все ще жахливе.
Джеймс

2
"Коли ви змушуєте збирати сміття?" для мене звучить як хороше запитання для інтерв’ю («Як»: не так вже й багато). Новачок: Не знаю. Середній: Ніколи. Експерт: Коли ви пишете тест на витоки пам'яті.
mikebridge

Відповіді:


193

System.GC.Collect()змушує збирач сміття працювати. Це не рекомендується, але можна використовувати, якщо виникають ситуації.


17
Чому це не рекомендується?
Люк Т О'Брайен

5
GC.Collect () запустити дорого. Робити це більше, ніж потрібно, недоцільно. Код, коли його слід викликати, добре написаний. Зазвичай ви повинні збирати самостійно лише у спеціалізованих кромках. stackoverflow.com/a/21961777/2710988
Брендон Барклі

190

Не рекомендується дзвонити gc явно, але якщо ви телефонуєте

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

Він буде дзвонити GC прямо в коді, не забудьте зателефонувати GC.WaitForPendingFinalizers();після GC.Collect().


14
WaitForPendingFinalizersне обов'язково дає "кращу продуктивність": він просто блокує, доки всі об'єкти в черзі завершення не будуть доопрацьовані (об'єкти, які могли бути поміщені туди під час вашого попереднього виклику Collect). Якщо ви хочете, щоб ці об’єкти були зібрані, вам потрібно ще один дзвінок Collect після дзвінка WaitForPendingFinalizers.
LukeH

2
Оскільки одна з небагатьох вагомих причин викликати gc.Collect - це остання спроба звільнити ресурси, які не були належним чином розпоряджені, WaitForPendingFinalizers видався б необхідним кроком. Не впевнені, якою найкращою практикою буде уникати виклику gc.Collect у таких випадках надмірно. До речі, мені цікаво, чи є якась технічна причина, через яку gc.Collect "має" сприяти просуванню поколінь? Здавалося б, більш корисним залишати покоління на місці, якщо в одному не виділено достатньо матеріалів, що виправдовують його просування.
supercat

3
Примітка для початківців у C # (як я): виклик сили GC не гарантує, деякі конкретні невикористані об'єкти будуть видалені з пам'яті. (один із способів це зробити - використання оператора " using " ( msdn.microsoft.com/ru-ru/library/yh598w02(v=vs.80).aspx ))
user1234567

Чому так важливо дзвонити WaitForPendingFinalizers?
Крістіан

19
GC.Collect() 

від MDSN ,

Використовуйте цей метод, щоб спробувати повернути всю недоступну пам’ять.

Всі об'єкти, незалежно від того, скільки часу вони перебувають у пам'яті, розглядаються для збору; однак об'єкти, на які посилаються в керованому коді, не збираються. Використовуйте цей метод, щоб змусити систему спробувати повернути максимальний обсяг доступної пам'яті.



12

GC.Collect();

Однак майте на увазі, що збирач сміття не завжди може прибрати те, що ви очікуєте ...


5
Що ти маєш на увазі? Що це могло несподівано очистити?
Волдеморт,

5
@Voldemort - Це нічого несподівано не очистить. Але це може не очистити все, що ви очікуєте.
Джастін Нісснер

6

Ви не хочете змушувати збирач сміття працювати.

Однак якщо ви коли-небудь це робили (звичайно, як суто академічну вправу):

GC.Collect()

4
Мені більше подобається відповідь @ Karthik, можуть бути ситуації, коли програма повинна законно викликати GC.Collect (). Хоча дуже рідко.
Хенк Холтерман

2
Скажімо, у вас був масив слабких посилань і ви хотіли перевірити, чи існують будь-які „живі” посилання. Мало би сенс викликати GC.Collect () перед перевіркою. Просто кажу.
Rich Ehmer

1
Проголосували проти, оскільки вступний вислів фактично неправильний; Так, я хочу змусити збирач сміття запуститись.
Syndog

5

Я думаю, що .Net Framework робить це автоматично, але про всяк випадок. Спочатку обов’язково виберіть те, що ви хочете стерти, а потім зателефонуйте до збирача сміття:

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();

Я думаю, це все .. Сподіваюся, я комусь допоможу.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.