5

J'ai un service WCF .NET 4 qui envoie au client de gros objets (~ 115Mb) qui sont désérialisés par le client. La première fois que l'objet entre en désérialisation. Cependant, tous les appels suivants jettent un OutOfMemoryException. J'ai vérifié pour m'assurer que tous mes IDisposables sont enveloppés dans using blocs. J'ai regardé les autres questions semblables à ceci comme BinaryFormatter outofmemory exception deserialization et Deserialize from MemoryStream throws OutOfMemory exception in C# . J'ai essayé certaines des solutions que les gens ont recommandées, y compris en utilisant Simon Hewitt's Optimized Serializer. Cependant, à la fin, il s'appuie toujours sur BinaryFormatter pour désérialiser les objets.Exception OutOfMemory de BinaryFormatter.Deserialize provenant de son appel interne StringBuilder

J'ai attrapé le OutOfMemoryException et regardé la trace de pile (voir ci-dessous). La trace semble provenir d'un problème d'utilisation de la mémoire dans la classe StringBuilder. J'ai lu d'autres articles sur la façon dont StringBuilder peut causer des problèmes de mémoire en raison de l'algorithme (longueur * 2) qu'ils utilisent lorsque plus d'espace est nécessaire.

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) 

Y at-il un moyen d'obtenir BinaryFormatter de travailler autrement et ne pas utiliser StringBuilder ou est-il une bonne alternative à BinaryFormatter qui gère la mémoire mieux?

+0

L'objet avait-il la même taille même lors du premier appel? Pouvez-vous poster du code, juste au cas où .. –

+0

Oui, c'était exactement la même réponse dans les deux cas. J'ai vérifié la taille exacte des octets à chaque fois pour être sûr. Je vais voir si je peux sortir du code, mais c'est assez long. – MrWuf

Répondre

1

Je ne recommanderais pas d'utiliser BinaryFormatter pour quelque chose de cette taille (en fait, il serait probablement beaucoup plus petit si vous n'utilisiez pas binaryformatter). Si ce sont des données assez simples telles que des données tabulaires ou avec des contraintes comme des références circulaires et ainsi de suite, alors rouler votre propre sérialisation binaire avec un simple binaire, ou utiliser un sérialiseur standard comme protobuf-net ou json.net devrait être plus compact et significativement plus rapide.

Questions connexes