使用gcAllowVeryLargeObjects时出现OutOfMemoryException

14

我正在使用BinarySerializer处理一个非常大(虽然不是很深)的项目图。我有8GB内存和12GB交换空间,当进行序列化时出现OutOfMemoryException异常,这是可以预料的(可能会接近或超过2GB)。

然而,即使使用gcAllowVeryLargeObjects也没有改善,我仍然遇到同样的异常,并且我确信正在处理应该在内存中容纳下的内容(至少通过交换空间)。

是否有什么方法来支持序列化此项目图/以分块方式获取相同的功能集并获得结果?

我的序列化代码没有任何特殊之处:

    public static byte[] Serialize(this object o)
    {
        var ms = new MemoryStream();
        var bf = new BinaryFormatter();
        bf.Serialize(ms, o);
        ms.Position = 0;
        return ms.ToArray();
    }

我正在序列化的对象包含着嵌套数组,这些数组本身还包含着其他数组等等,但整个序列化图并没有那么大(它是对源数据进行索引后只有约1GB大小的结果)。

这也不是因为垃圾回收碎片问题(压缩大堆并不能解决问题)。


3
你使用的操作系统是64位的吗? - Jean Hominal
你为什么要在内存中序列化这么大的东西,而不是文件呢?如果我看得对的话,在执行的某个单一点上,你的内存需求至少是结构体大小的3倍(结构体本身、其中的MemoryStream内容和来自MemoryStream的字节数组)。你能否改为序列化到文件中呢? - LB2
@AlexeiLevenkov 在64位操作系统上使用AnyCPU(所以应该是64位,除非我误解了?) - Ronan Thibaudau
3
除非取消“优先选择32位”,否则它将是x86架构。 - Alexei Levenkov
2
你的代码中缺少 using 关键字来包含 MemoryStream,这可能会导致内存问题(虽然并非核心问题)。 - LB2
显示剩余6条评论
1个回答

18

默认情况下,AnyCPU 在 x86 和 x64 操作系统上都作为 32 位进程运行。因此,即使在 x64 操作系统上设置了 gcAllowVeryLargeObjects ,您仍然会遇到地址空间的 4GB 限制(x86 上为 2GB)。

要更改,请取消选中“解决方案属性” ->“生成”选项卡上的“优先使用 32 位”属性。

有关详细信息和历史记录,请参见以下答案:什么是 Visual Studio 2012 中“优先使用 32 位”设置的目的,它实际上是如何工作的?


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