Вызов GC.Collect() нужен для сборки объектов в 1 и во 2 поколениях. То что в 0 поколении и так прекрасно собирается. Но то что переживает 0-вое поколение, т.е. объекты в 1-ом и во 2-ом поколениях, очень редко удостаиваются внимания сборщика, если нет жесткого прессинга по памяти. При этом, очень большие объекты, в том числе массивы, при создании помещаются сразу в кучу во 2-ое поколение.
Соответственно, нужно чтобы совпало:
1) В программе есть некоторая операция, которая создает очень большой объект, такой, что он сразу попадает во 2-ое поколение.
2) Свободной памяти на сервере больше нет, либо очень мало.
3) Нужно избежать простоя, связанного со сборкой мусора, при запуске следующей подобной операции.
4) В некоторой точке программы точно можно гарантировать, что нет ни одной ссылки на тот большой объект (иначе GC его не удалит)
И только тогда можно дернуть GC.Collect(). Иначе смысла вызывать его нет.
Т.е. вы на сто процентов уверены, что будет задержка вызванная сборкой мусора, и именно тем, что сборщик полезет чистить 1-ое и 2-ое поколение, но вас не устраивает то, когда именно произойдет эта задержка, и вы переносите её на более ранее время (возможно более подходящее/приемлемое) принудительным вызовом GC.Collect().
Главное нужно понимать, что GC.Collect() волшебным образом не очистит память. Чтобы этот вызов что-то почистил нужно быть на 100% уверены, что в памяти есть объекты на которые нет ссылок, но которые застряли в памяти. Иными словами, что нет утечек памяти. (да да, программы на дот.нет тоже могут течь) Как правило, если устранить утечки, т.е. выстроить правильную работу с памятью, то потребность принудительно указывать сборщику мусора отпадет сама собой.