Как заставить сборщик мусора работать?


148

Интервьюер спросил меня об этом сегодня ... есть ответ?


3
Этот вопрос содержит хорошую информацию о том, почему вы не должны этого делать: stackoverflow.com/questions/118633/…
— Ганс Олссон

1
почему ты так говоришь
— Эндрю Коллинз

1
@ Джейсон - Может быть, интервьюер не хотел слышать решение, а скорее получить знания Эндрю и аргументации против этого, тогда этот вопрос может иметь смысл.
— martinstoeckli

2
@martinstoeckli Это все еще ужасный вопрос. Кто-то, обладающий знаниями в стрессовом интервью, не поймет, что это вопрос с подвохом, или подумает предоставить дополнительную информацию. Тогда вопрос не помогает интервьюеру отличить кого-то со знанием или от кого-то без него. Так что вопрос все еще ужасен.
— Джеймс

2
"Когда вы заставляете сбор мусора?" звучит как хороший вопрос для интервью («Как»: не так много). Новичок: я не знаю. Средний: Никогда. Эксперт: Когда вы пишете тест на утечки памяти.
— Майкбридж

Ответы:


188

System.GC.Collect()заставляет сборщик мусора бежать. Это не рекомендуется, но может быть использовано в случае возникновения ситуаций.


17
Почему это не рекомендуется?
— Люк Т О'Брайен

5
GC.Collect () стоит дорого. Делать это больше, чем необходимо, нецелесообразно. Код для того, когда он должен быть вызван, хорошо написан. Обычно вы должны самостоятельно собирать только в специализированных случаях. stackoverflow.com/a/21961777/2710988
— Брэндон Баркли

187

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

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

Он будет вызывать GC явно во всем вашем коде, не забудьте позвонить GC.WaitForPendingFinalizers();после GC.Collect().


14
WaitForPendingFinalizersне обязательно дает «лучшую производительность»: он просто блокируется, пока все объекты в очереди завершения не будут завершены (объекты, которые могли быть помещены туда при предыдущем вызове Collect). Если вы хотите, чтобы эти объекты были собраны, вам нужен еще один вызов Collect после вызова WaitForPendingFinalizers.
— ЛукиH

2
Поскольку одной из немногих веских причин для вызова gc.Collect является последняя попытка освободить ресурсы, которые не были должным образом утилизированы, WaitForPendingFinalizers может показаться необходимым шагом. Не уверен, что лучше всего избегать чрезмерного вызова gc.Collect в таких случаях. Кстати, мне интересно, есть ли какая-то техническая причина, по которой gc.Collect «продвигает поколения»? Казалось бы, более полезно, чтобы поколения оставались на месте, если в одном не было выделено достаточное количество материала, чтобы оправдать его продвижение.
— суперкат

2
Примечание для начинающих в C # (как и я): принудительный вызов GC не гарантирует, что какой-то конкретный неиспользуемый объект будет удален из памяти. (один из способов сделать это - использовать выражение «using» ( msdn.microsoft.com/ru-ru/library/yh598w02(v=vs.80).aspx ))
— user1234567

Почему должно быть важно позвонить WaitForPendingFinalizers?
— Кристиан

19
GC.Collect() 

из МДСН ,

Используйте этот метод, чтобы попытаться восстановить всю память, которая недоступна.

Все объекты, независимо от того, как долго они были в памяти, рассматриваются для сбора; однако объекты, на которые есть ссылки в управляемом коде, не собираются. Используйте этот метод, чтобы заставить систему попытаться восстановить максимальный объем доступной памяти.



12

GC.Collect();

Имейте в виду, однако, что сборщик мусора не всегда может очистить то, что вы ожидаете ...


5
Что ты имеешь в виду? Что это может неожиданно очистить?
— Волдеморт

5
@ Voldemort - это ничего не очистит неожиданно. Но это может не очистить все, что вы ожидаете.
— Джастин Нисснер

6

Вы не хотите принудительно запускать сборщик мусора.

Однако, если вы когда-либо делали (как чисто академическое упражнение, конечно):

GC.Collect()

4
Я предпочитаю ответ @ Karthik, могут быть ситуации, когда приложение должно законно вызвать GC.Collect (). Хотя очень редко.
— Хенк Холтерман

2
Скажем, у вас есть массив слабых ссылок и вы хотите проверить, существуют ли какие-либо «живые» ссылки. Имеет смысл вызвать GC.Collect () перед проверкой. Просто говорю.
— Рич Эмер

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.