Несколько причин:
GC работает в свое приятное время; обычно, когда время выполнения не хватает памяти. Вот почему удаление объектов, таких как соединения с БД, важно; да, они будут выпущены в конце концов, но не раньше, чем GC соизволит бежать.
GC.Collect () не запускает поток GC напрямую; это планирует прогон GC. Опять же, среда выполнения обычно запускает GC только тогда, когда обнаруживает, что песочница загромождена, или если существует значительное время простоя. GC.Collect () - это переопределение, которое ведет себя так же, как если бы произошел один из этих автоматических триггеров. это не встроенный вызов для запуска алгоритма сборки мусора; это может привести к заметному снижению производительности.
GC работает в своем собственном потоке. Поэтому информация, предоставляемая статическими методами GC, основана на том, что доступно вызывающей стороне во время ее вызова. Вы вызываете GetTotalMemory в последний раз, когда GC все еще работает, или, может быть, даже до того, как он даже запустился, и поэтому показатели памяти не были обновлены с учетом того, что GC завершает.
Таким образом, GC разработан, чтобы быть в значительной степени невмешательным. GC.Collect () эквивалентно вешанию знака «пожалуйста, обслуживайте» на двери вашего отеля; это предположение, что, возможно, сейчас самое время очистить.