我正在对 .NET 2.0 Windows 服务应用程序中的 OutOfMemory 异常进行故障排除。为了更好地理解这个问题,我首先编写了一个简单的 .NET WinForm 测试应用程序,该应用程序通过构建一个 ArrayList 直到引发 OOM 异常来生成 OOM 异常。异常被捕获并记录下来,我可以单击表单按钮再次运行 OOME。我发现奇怪的是在第 4 次运行时,下一次 OOME 之前消耗的内存量大约是一半。每次运行时,下面列出的结果都是一致的。Eyeballing TaskManager 也确认了该行为。不幸的是,Perfmon 在试图获得更好的统计数据时冻结了。有人可以解释为什么 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