5

我有一個.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來反序列化對象。來自BinaryFormatter.Deserialize的OutOfMemory異常來自其內部的StringBuilder調用

我抓到OutOfMemoryException,看着堆棧跟蹤(見下文)。跟蹤看起來源自StringBuilder類中的內存使用情況。我已閱讀其他有關StringBuilder如何在需要更多空間時由於使用(長度* 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管理內存更好的一個很好的選擇?

+0

即使在第一次調用中,是否具有相同大小的對象?你可以發佈一些代碼,以防萬一.. –

+0

是的,這兩種情況下都是完全相同的響應。我每次檢查確切的字節大小以確保。我會看看我是否可以取出一些代碼,但這是相當長的。 – MrWuf

回答

1

我不會推薦使用BinaryFormatter來處理任何大小的事情(事實上,如果你不使用binaryformatter,它可能會小很多)。如果它是相當簡單的數據,如表格數據或一些約束條件(如無循環引用等),那麼使用簡單的二進制編寫器或使用一些現成的序列化器(如protobuf-netjson.net)來滾動您自己的二進制序列化應該更加緊湊,明顯更快。