我正在解决一个在我的.NET 2.0 Windows服务应用程序中出现的OutOfMemory异常。为了更好地理解问题,我首先编写了一个简单的.NET WinForm测试应用程序,通过构建一个ArrayList直到抛出OutOfMemory异常来生成一个OOM异常。异常被捕获并记录下来,我可以点击表单按钮再次运行OOME。我发现奇怪的事情是,在第四次运行之前消耗的内存大约减少了一半。每次运行时列出的结果都是一致的。眼观TaskManager也确认了这种行为。不幸的是,在尝试获取更好的统计数据时,Perfmon冻结了。有人能解释一下为什么在3次运行后内存限制会降低吗?我对GC的理解还比较浅显。你还可以看到我在几次运行后运行了GC.Collect(),但它没有帮助降低限制。
更新:我还发现使用const字符串与为每个arraylist项创建一个新对象之间存在很大的差异。代码非常简单:
更新:我还发现使用const字符串与为每个arraylist项创建一个新对象之间存在很大的差异。代码非常简单:
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