我有一个.NET 4 WCF服务,该服务正在向客户端发送一些被客户端反序列化的大对象(〜115Mb)。对象第一次进入时会反序列化良好。但是,所有后续调用都将抛出OutOfMemoryException
。我已检查以确保所有IDisposables
都包裹在using
块中。我看过其他类似的问题,例如BinaryFormatter outofmemory exception deserialization和Deserialize from MemoryStream throws OutOfMemory exception in C#。我已经尝试了人们推荐的一些解决方案,包括使用Simon Hewitt's Optimized Serializer。但是,最后,他仍然依赖BinaryFormatter
对对象进行反序列化。
我捕获了OutOfMemoryException
并查看了堆栈跟踪(请参见下文)。跟踪似乎源自StringBuilder
类中的内存利用率问题。我已经阅读了其他有关StringBuilder
如何由于需要更多空间而使用(length * 2)算法而导致内存问题的文章。
at System.Text.StringBuilder.ToString()
at System.IO.BinaryReader.ReadString()
at System.Runtime.Serialization.Formatters.Binary.__BinaryParser.ReadObjectString(BinaryHeaderEnum binaryHeaderEnum)
at System.Runtime.Serialization.Formatters.Binary.__BinaryParser.Run()
at System.Runtime.Serialization.Formatters.Binary.ObjectReader.Deserialize(HeaderHandler handler, __BinaryParser serParser, Boolean fCheck, Boolean isCrossAppDomain, IMethodCallMessage methodCallMessage)
at System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Deserialize(Stream serializationStream, HeaderHandler handler, Boolean fCheck, Boolean isCrossAppDomain, IMethodCallMessage methodCallMessage)
at System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Deserialize(Stream serializationStream)
有没有一种方法可以让
BinaryFormatter
正常工作并且不使用StringBuilder
,或者是否可以使用BinaryFormatter
更好地管理内存? 最佳答案
我不建议将BinaryFormatter用于任何大小的文件(实际上,如果您不使用BinaryFormatter,它可能会小很多)。如果它是相当简单的数据(例如表格数据)或具有某些约束(例如没有循环引用等),则使用简单的二进制编写器滚动您自己的二进制序列化,或者使用一些现成的序列化器(例如protobuf-net或json.net)应该更紧凑,并且明显更快。
关于c# - BinaryFormatter.Deserialize的OutOfMemory异常来自其内部StringBuilder调用,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/10851285/