5

У меня есть служба WCF .NET 4, которая отправляет клиенту некоторые большие объекты (~ 115Mb), которые десериализуются клиентом. При первом входе в объект десериализуется штраф. Однако все последующие вызовы вызывают OutOfMemoryException. Я проверил, чтобы все мои IDisposables были обернуты в блоки using. Я рассмотрел другие вопросы, подобные этому, такие как BinaryFormatter outofmemory exception deserialization и Deserialize from MemoryStream throws OutOfMemory exception in C# . Я пробовал некоторые из решений, рекомендованных людьми, включая использование Simon Hewitt's Optimized Serializer. Однако, в конце концов, он все еще полагается на BinaryFormatter для десериализации объектов.Исключение OutOfMemory из BinaryFormatter.Deserialize, исходящее из его внутреннего вызова 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 для чего-либо такого размера (на самом деле это было бы намного меньше, если бы вы не использовали двоичный формат). Если это довольно простые данные, такие как табличные данные или с некоторыми ограничениями, например, без круговых ссылок и т. Д., То перенос вашей собственной двоичной сериализации с помощью простого двоичного писателя или использование некоторых из сериализатора полки, такого как protobuf-net или json.net, должны быть более компактными и значительно быстрее.