在我的应用程序中,我点击一个添加按钮,将一个新的1GB字节数组添加到列表中。我看到我的系统内存使用量增加了1GB。我总共点击了6次添加按钮,填满了我开始时可用的6GB内存。
我点击一个删除按钮6次,从列表中删除每个数组。被删除的字节数组不应该被我控制的任何其他对象引用。
当我删除时,我没有看到内存减少。 但这对我来说没关系,因为我知道垃圾回收是非确定性的之类的。 我认为垃圾回收会根据需要进行收集。
所以现在内存看起来已经满了,但是期望垃圾回收在需要时进行收集,我再次进行添加操作。 我的电脑开始陷入磁盘抖动的昏迷状态。 为什么垃圾回收没有进行? 如果那不是时候,那什么时候呢?
作为一个合理性检查,我有一个按钮来强制进行垃圾回收。当我按下按钮时,我很快就能够回收6GB的内存。这难道不证明我的6个数组没有被引用,并且如果垃圾回收知道/愿意的话,它们本可以被回收吗?
我读了很多关于不应该调用GC.Collect()的文章,但是在这种情况下,如果垃圾回收不进行回收,我还能做什么呢?
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 expect 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();
}