5

Ho un servizio WCF .NET 4 che invia al client alcuni oggetti grandi (~ 115 Mb) che vengono deserializzati dal client. La prima volta che l'oggetto entra deserializza bene. Tuttavia, tutte le chiamate successive generano uno OutOfMemoryException. Ho controllato per assicurarmi che tutti i miei IDisposables siano incapsulati nei blocchi using. Ho esaminato le altre domande simili a questa come BinaryFormatter outofmemory exception deserialization e Deserialize from MemoryStream throws OutOfMemory exception in C# . Ho provato alcune delle soluzioni raccomandate dalle persone, incluso l'utilizzo di Simon Hewitt's Optimized Serializer. Tuttavia, alla fine, si affida ancora allo BinaryFormatter per deserializzare gli oggetti.Eccezione OutOfMemory da BinaryFormatter.Deserialize proveniente dalla sua chiamata StringBuilder interna

Ho preso lo OutOfMemoryException e ho guardato la traccia dello stack (vedi sotto). La traccia sembra provenire da un problema con l'utilizzo della memoria nella classe StringBuilder. Ho letto altri articoli su come StringBuilder possono causare problemi di memoria dovuti all'algoritmo (lunghezza * 2) che usano quando è necessario più spazio.

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) 

C'è un modo per ottenere BinaryFormatter a lavorare in modo diverso e non utilizzare StringBuilder o c'è una buona alternativa a BinaryFormatter che gestisce la memoria migliore?

+0

L'oggetto della stessa dimensione era già nella prima chiamata? Puoi pubblicare del codice, nel caso in cui .. –

+0

Sì, è stata la stessa risposta esatta in entrambi i casi. Ho controllato ogni volta la dimensione esatta del byte per essere sicuro. Vedrò se riesco a estrarre qualche codice, ma è piuttosto lungo. – MrWuf

risposta

1

Non mi consiglia di utilizzare BinaryFormatter per qualsiasi dimensione (in effetti sarebbe probabilmente molto più piccolo se non si utilizzasse il formato binario). Se si tratta di dati abbastanza semplici come dati tabellari o con alcuni vincoli come nessun riferimento circolare e così via, eseguire la serializzazione binaria con un semplice writer binario o utilizzare alcuni serializzatori come protobuf-net o json.net dovrebbe essere più compatto e significativamente più veloce.