【发布时间】:2015-10-30 09:33:44
【问题描述】:
我正在使用 c# 和 .net 4.5。
我有一个类 SomeData,它包含一个成员 _SomeEvents,它是一个字典。 SomeData 类还包含一堆信息,例如生成数据的时间、生成数据的用户等。
我正在尝试使用 formatter.Serialize 将 SomeData 对象保存到文件,但是当对象很大(例如 1GB)时遇到 OutOfMemoryException
IFormatter formatter = new BinaryFormatter();
Stream stream;
stream = new FileStream(filePath, FileMode.Create, FileAccess.Write, FileShare.None);
formatter.Serialize(stream, _myObject);
stream.Close();
我读过的其他帖子表明,内存不足问题是由于无法找到足够大的连续可用内存区域来生成要写入磁盘的数据。我还读到这是一种“错误”的序列化方式——我的假设是,如果我做得正确,CLR 会随时写入数据,而不是在保存之前尝试在内存中准备所有数据。也就是说 - 我确实看到在序列化操作失败之前创建了一个大文件,这意味着它正在写入。
我尝试更改序列化操作以编写 Dictionary 对象本身而不是包含 Dictionary 的对象 - 同样的问题,我得到内存异常。
问题:
- 为什么 Serialize 会遇到这个内存问题 - 即使我给它一个 Dictionary 对象来序列化 - 它肯定会按原样写入?
- 有更好的方法吗?!!
这是完整的例外:
无法保存文件:System.OutOfMemoryException:引发了“System.OutOfMemoryException”类型的异常。
在 System.Runtime.Serialization.ObjectIDGenerator.Rehash()
在 System.Runtime.Serialization.ObjectIDGenerator.GetId(Object obj, Boolean& firstTime)
在 System.Runtime.Serialization.Formatters.Binary.ObjectWriter.InternalGetId(Object obj, Boolean assignUniqueIdToValueType, Type type, Boolean& isNew)
在 System.Runtime.Serialization.Formatters.Binary.ObjectWriter.WriteString(NameInfo memberNameInfo, NameInfo typeNameInfo, Object stringObject)
在 System.Runtime.Serialization.Formatters.Binary.ObjectWriter.WriteKnownValueClass(NameInfo memberNameInfo, NameInfo typeNameInfo, Object data)
在 System.Runtime.Serialization.Formatters.Binary.ObjectWriter.WriteMembers(NameInfo memberNameInfo, NameInfo memberTypeNameInfo, Object memberData, WriteObjectInfo objectInfo, NameInfo typeNameInfo, WriteObjectInfo memberObjectInfo)
在 System.Runtime.Serialization.Formatters.Binary.ObjectWriter.WriteMemberSetup(WriteObjectInfo objectInfo, NameInfo memberNameInfo, NameInfo typeNameInfo, String memberName, Type memberType, Object memberData, WriteObjectInfo memberObjectInfo)
在 System.Runtime.Serialization.Formatters.Binary.ObjectWriter.Write(WriteObjectInfo objectInfo, NameInfo memberNameInfo, NameInfo typeNameInfo, String[] memberNames, Type[] memberTypes, Object[] memberData, WriteObjectInfo[] memberObjectInfos)
在 System.Runtime.Serialization.Formatters.Binary.ObjectWriter.Write(WriteObjectInfo objectInfo, NameInfo memberNameInfo, NameInfo typeNameInfo)
在 System.Runtime.Serialization.Formatters.Binary.ObjectWriter.Serialize(Object graph, Header[] inHeaders, __BinaryWriter serWriter, Boolean fCheck)
在 System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Serialize(Stream serializationStream, Object graph, Header[] headers, Boolean fCheck)
在 System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Serialize(Stream serializationStream, Object graph)
【问题讨论】:
-
谢谢,虽然看起来stackoverflow.com/questions/25148793/… 在正确的区域。我将尝试一次处理我的每个事件 1(或 x)的序列化操作,看看是否可以使用 BinaryFormatter 图形序列化程序避免这个问题
-
我刚刚切换到 protobuf-net,我的记忆问题消失了!诚然,我最终得到了一个 400MB 的 1m 事件文件,但我可以将它写入一个临时文件,然后在进行初始反序列化后将其压缩到 8MB。
标签: c# .net serialization clr