gpt4 book ai didi

.net - 了解 .NET GC 和 OutOfMemory 异常

转载 作者:行者123 更新时间:2023-12-02 15:43:26 25 4
gpt4 key购买 nike

我正在对 .NET 2.0 Windows 服务应用程序中的 OutOfMemory 异常进行故障排除。为了更好地理解这个问题,我首先编写了一个简单的 .NET WinForm 测试应用程序,该应用程序通过构建 ArrayList 来生成 OOM 异常,直到抛出 OOM 异常。捕获并记录异常,我可以单击表单按钮再次运行 OOME。我发现奇怪的事情是在第四次运行时,下一次 OOME 之前消耗的内存量大约是一半。每次运行时,下面列出的结果都是一致的。观察 TaskManager 也证实了这一行为。不幸的是,当佩尔夫蒙试图获得更好的统计数据时,他愣住了。有人可以解释为什么运行 3 次后内存限制会降低吗?我对GC的理解还比较肤浅。您还可以看到我在几次运行后运行了 GC.Collect(),但它对降低限制没有帮助。

更新:我还发现对于每个数组列表项使用 const 字符串与新对象有很大区别。代码很简单:

const string TEST_TEXT = "xxxxxxxxxx";
ArrayList list = new ArrayList();
while (true)
{
list.Add(TEST_TEXT);
}
<小时/>

开始循环:内存10,350,592

  • 抛出 OOM 异常
  • 数组大小:134,217,728

结束循环:内存550,408,192

启动循环:内存550,731,776

  • 抛出 OOM 异常
  • 数组大小:134,217,728

结束循环:内存551,682,048

启动循环:内存551,813,120

  • 抛出 OOM 异常
  • 数组大小:134,217,728

结束循环:内存551,772,160

启动循环:内存551,903,232

  • 抛出 OOM 异常
  • 数组大小:67,108,864

结束循环:内存282,869,760

启动循环:内存283,004,928

  • 抛出 OOM 异常
  • 数组大小:67,108,864

结束循环:内存282,910,720

GC.Collect手动触发

启动循环:内存14,245,888

  • 抛出 OOM 异常
  • 数组大小:67,108,864

结束循环:内存283,344,896

最佳答案

以下几点综合起来,希望能为您提供足够的信息来回答您的问题:

  • 不管它的名字如何,OutOfMemory exceptions are just as likely to mean you are out of Address Space as physical RAM.
  • GC.Collect不会收集所有未使用的 RAM。 .Net 中的垃圾收集是非确定性的,这意味着无法强制运行时清理所有 RAM。
  • .Net 中的垃圾收集器是分代的,这意味着当对象在收集中幸存下来时,它会移动到更高的一代,从而使其被收集的可能性更小。
  • 当抛出 OutOfMemory 异常时,您的数组可能已经在几次收集尝试中幸存下来,甚至已移至 LargeObjectHeap。
  • 数组大小是固定的。要向数组添加新元素,您必须完全重新分配数组。 (使用列表等结构可能会获得更好的测试结果。

关于.net - 了解 .NET GC 和 OutOfMemory 异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1336660/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com