我制作了一个 64 位 WPF 测试应用程序。在我的应用程序运行并打开任务管理器的情况下,我观察我的系统内存使用情况。我看到我正在使用 2GB,并且我有 6GB 可用。
在我的应用程序中,我单击添加按钮以将新的 1GB 字节数组添加到列表中。我看到我的系统内存使用量增加了 1GB。我一共点击了 6 次添加,填满了我开始时可用的 6GB 内存。
我单击“删除”按钮 6 次以从列表中删除每个数组。删除的字节数组不应被我控件中的任何其他对象引用。
当我删除时,我没有看到我的记忆下降。但这对我来说没问题,因为我知道 GC 是非确定性的。我认为 GC 将根据需要收集。
因此,现在内存看起来已满,但希望 GC 在需要时收集,我再次添加。我的电脑开始滑入和滑出磁盘抖动昏迷。为什么GC没有收集?如果那不是做的时候,那是什么时候?
作为健全性检查,我有一个强制 GC 的按钮。当我推动它时,我很快就恢复了 6GB。这不是证明我的 6 个数组没有被引用,并且如果 GC 知道/想要的话,可以收集吗?
我读过很多说我不应该调用 GC.Collect() 但如果 GC 在这种情况下不收集,我还能做什么?
private ObservableCollection<byte[]> memoryChunks = new ObservableCollection<byte[]>();
public ObservableCollection<byte[]> MemoryChunks
{
get { return this.memoryChunks; }
}
private void AddButton_Click(object sender, RoutedEventArgs e)
{
// Create a 1 gig chunk of memory and add it to the collection.
// It should not be garbage collected as long as it's in the collection.
try
{
byte[] chunk = new byte[1024*1024*1024];
// Looks like I need to populate memory otherwise it doesn't show up in task manager
for (int i = 0; i < chunk.Length; i++)
{
chunk[i] = 100;
}
this.memoryChunks.Add(chunk);
}
catch (Exception ex)
{
MessageBox.Show(string.Format("Could not create another chunk: {0}{1}", Environment.NewLine, ex.ToString()));
}
}
private void RemoveButton_Click(object sender, RoutedEventArgs e)
{
// By removing the chunk from the collection,
// I except no object has a reference to it,
// so it should be garbage collectable.
if (memoryChunks.Count > 0)
{
memoryChunks.RemoveAt(0);
}
}
private void GCButton_Click(object sender, RoutedEventArgs e)
{
GC.Collect();
GC.WaitForPendingFinalizers();
}