C#垃圾回收不释放内存

5
我在使用C#时遇到了一个糟糕的问题,即在我不再引用大型结构体时,C#不能释放其占用的内存。下面的代码展示了类似于我的问题,但我认为我对GC的理解可能有误,因为我不确定为什么以下代码会抛出内存不足异常。有人知道为什么我包含的代码会出现内存不足的情况吗?这些列表中没有一个被保留,它们应该能够立即清除。谢谢!重现:创建一个全新的4.5控制台应用程序,将代码粘贴到Main中。抛出异常将在for循环的第三个"new List"上发生,在省略for循环的情况下,将不会发生内存不足的情况。
for (var i = 0; i < 100; i++)
{
    new List<int>(100 * 1000 * 1000);
    GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced, blocking: true);
    new List<int>(100 * 1000 * 1000);
    GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced, blocking: true);
    new List<int>(100 * 1000 * 1000);
    GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced, blocking: true);
    new List<int>(100 * 1000 * 1000);
    GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced, blocking: true);
}

这只是我的个人意见,但如果你需要进行大量的细粒度内存管理和垃圾回收,C#可能不是最合适的工具。像C/C++这样的语言可能更适合。 - Gray
这些代码中哪一行会抛出异常?是第一行还是其他行? - Sebastian Negraszus
对我来说,在第三个“new List”处出现了异常... 如果你复制并粘贴几次,你仍然没有得到异常吗? - skippy10110
我无法重现这个问题。请列出目标 Fx、Fx 版本、操作系统和硬件,并确保实际代码产生了错误。 - H H
我更新了我的问题,似乎是for循环触发了错误,即使它从未进行第二次迭代。 - skippy10110
显示剩余5条评论
1个回答

4

好的,这个问题确实可以在以下情况下重现:

  • Fx 4.5,平台 = Any CPU,配置 = Debug。

选择 x64 平台或 Release 模式后,程序将按预期运行。

因此,初步结论是:没有优化时,List<> 在不应该存在的位置仍然保持根源。因此,GC 调用根本没有效果,x86 内存空间很快耗尽。

这可能是一个错误,也可能是旨在进行调试的“特性”。

但是,虽然似乎存在问题,但很容易避免。


即使选择了发布模式,我仍然遇到错误。 - skippy10110
确定一下,[]optimize被勾选了吗? - H H
我相信这实际上是与调试相关的“特性”,但我并不100%确定。我曾经读过一个很好的SO答案,解释了类似于这样的东西,不久前,我会尝试找到它(实际上,我最初以为你写了回复。也许不是)。当然,如果OP正确,并且它发生在优化的构建中...那么这是错误的。 - Ed S.
我认为是汉斯,他链接到了重复的内容。 - H H
我确实快速浏览了一下,今晚我会再看一遍。感谢链接和帮助! - skippy10110
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接