【发布时间】:2013-09-09 10:29:23
【问题描述】:
在提问之前,我先做一个小小的免责声明: 是的,我知道虚拟内存、物理内存和工作集之间的区别。以下所有数字均指虚拟内存。
情况如下: 我们有一个 32 位 C# 应用程序,它导入 x86 C++ 库(具有大量本机依赖项,因此目前无法迁移到 x64)。 应用通过非托管组件加载大型数据集,然后尝试显示(报告)。
但是,当数据集特别大时,在向列表中添加项目时会引发 OutOfMemory 异常,如下面的代码所示:
这并不奇怪。然而,令人惊讶的是,该应用程序仍有大约 280MB 的空闲 VM。
在调试纯非托管应用程序 (C++) 时,情况并非如此 - 只有在没有空闲 VM 或没有足够大小的空闲地址空间块时才能实现 bad_alloc。
因此,问题 - 这可能是什么原因?我了解如何解决这个问题 - 非托管组件确实会占用大量内存,并且会产生大量碎片 - 但是 OutOfMemoryException 这么早出现的原因是什么?
有问题的代码如下所示:
List<Cell> r = new List<Cell>(cols);
for (int j = 0; j < cols; j++)
{
r.Add(new CustomCell()); // The exception is thrown on this line
}
在异常发生时,列表(一次出现)有 85 个项目,其容量为 200 左右(列数,如构造函数中所示)。因此,异常很可能发生在 CustomCell 分配中。 CustomCell 对象有很多字段,但总和肯定小于 1KB。 280MB 的空闲内存位于 64KB 到 14MB 的块中 - 所以应该有足够的空间来分配它。
【问题讨论】:
-
也许问题是内存碎片。您有足够的可用内存,但缺少足够大的连续块来存储新数据。
-
当然不是这样。我已经使用 Sysinternals 和 Visual Studio 的 VMMap 实用程序调查了应用程序内存 - 有高达 14Mb 的空闲块。失败的操作是创建一个小于 1KB 的对象。
-
OutOfMemory exception is thrown upon adding an item to the list.这里的列表是什么? -
用一段代码更新了问题。
标签: c# .net memory-management out-of-memory