我已閱讀此文章:http://blogs.msdn.com/b/oldnewthing/archive/2010/08/10/10048149.aspx,說實話,我不明白每一個細節。據我所知,在下面的代碼中,即使我沒有將c設置爲null,也應該收集c。另一件事是,只要我們在同一個函數的範圍內,在foreach期間發生的分配似乎沒有被釋放。 (參見下面的示例)收集仍在範圍內的物體--GC.Collect
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,它將按預期工作:即使沒有設置爲null,也會收集到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循環放在另一個函數中,並調用這個函數,在.Col之後使用這個函數lect是調用約爲5800000.那麼,爲什麼當我在同一個函數中有foreach循環時垃圾不會被收集?
http://msdn.microsoft.com/en-us/library/xe0c2357.aspx 這不是確定性的,但可以強制收集未收集到的對象。 GC.GetTotalMemory(true)等待當前集合完成。所以至少應該釋放一些數據。這不會是每次嘗試相同的金額是可以的,但不會有200 MB的差異... – SACO
@Malone它不是確定性的。所以短語「所以至少應該釋放一些數據」並不適用。爲了能夠說它必須是確定性的。 – Rangoric