Я прочитал эту статью: http://blogs.msdn.com/b/oldnewthing/archive/2010/08/10/10048149.aspx и, честно говоря, я не понимаю всех деталей.Насколько я понимаю, в приведенном ниже коде c следует собирать, даже если я не установил для c значение null.Другое дело, что распределение, происходящее во время foreach, кажется, не освобождается, пока мы находимся в рамках одной и той же функции.(См. Пример ниже)
class Program
{
public class SomeClass
{
public byte[] X;
public SomeClass()
{
X = new byte[1024 * 1024 * 100];
X[155] = 10;
}
}
static void Main()
{
Console.WriteLine("Memory: " + GC.GetTotalMemory(false));
SomeClass c;
c = new SomeClass();
Console.WriteLine("Memory: " + GC.GetTotalMemory(false));
GC.Collect();
Console.WriteLine("Memory: " + GC.GetTotalMemory(true));
Console.ReadKey();
/*
* Output:
*
* Memory: 186836
* Memory: 105044468
* Memory: 104963676
*
*/
}
}
EDIT Решение для первого примера: режим отладки (не работает в отладчике, но даже в режиме компиляции).Если я использую Release, он будет работать как положено: c собирается даже без установки на ноль.Для второго примера применяется то же самое.
Второй пример
static void Main(string[] args)
{
Console.WriteLine("Startup Memory: " + GC.GetTotalMemory(false));
var obj = BOObject.Get();
Console.WriteLine("Fetched Object: " + GC.GetTotalMemory(false));
GC.Collect();
Console.WriteLine("Fetched Object (Collected): " + GC.GetTotalMemory(false));
foreach (var node in obj.Traverse())
{
string name = node.Name;
}
Console.WriteLine("Traversed: " + GC.GetTotalMemory(false));
GC.Collect();
Console.WriteLine("Traversed (collected): " + GC.GetTotalMemory(false));
obj = null;
GC.Collect();
Console.WriteLine("collected: " + GC.GetTotalMemory(true));
Console.Read();
}
Вывод:
Память при запуске: 193060 Извлечено: 8972464 Извлечено (собрано): 5594308 Пройдено: 272553096 Просмотрено (собрано): 269564660 собрано: 269564048
Если я помещаю цикл foreach в другую функцию и вызываю эту функцию, то используемая память после вызова .Collect составляет около 5800000. Так почему мусор не собирается, когда у меня есть foreachцикл в той же функции?