La situazione è che sto effettuando una chiamata WCF a un server remoto che restituisce un documento XML come stringa.Maxmise il più grande blocco di memoria contiguo nell'heap a oggetti grandi
Il più delle volte questo valore di ritorno è a pochi K, a volte qualche decina K, molto occasionalmente qualche centinaio di K, ma molto raramente potrebbe essere diversi megabyte (primo problema è che non c'è modo per me sapere).
Queste rare occasioni causano dolore. Ottengo una traccia dello stack che inizia:
System.OutOfMemoryException: Exception of type 'System.OutOfMemoryException' was thrown.
at System.Xml.BufferBuilder.AddBuffer()
at System.Xml.BufferBuilder.AppendHelper(Char* pSource, Int32 count)
at System.Xml.BufferBuilder.Append(Char[] value, Int32 start, Int32 count)
at System.Xml.XmlTextReaderImpl.ParseText()
at System.Xml.XmlTextReaderImpl.ParseElementContent()
at System.Xml.XmlTextReaderImpl.Read()
at System.Xml.XmlTextReader.Read()
at System.Xml.XmlReader.ReadElementString()
at Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationReaderMDRQuery.Read2_getMarketDataResponse()
at Microsoft.Xml.Serialization.GeneratedAssembly.ArrayOfObjectSerializer2.Deserialize(XmlSerializationReader reader)
at System.Xml.Serialization.XmlSerializer.Deserialize(XmlReader xmlReader, String encodingStyle, XmlDeserializationEvents events)
at System.Xml.Serialization.XmlSerializer.Deserialize(XmlReader xmlReader, String encodingStyle)
at System.Web.Services.Protocols.SoapHttpClientProtocol.ReadResponse(SoapClientMessage message, WebResponse response, Stream responseStream, Boolean asyncCall)
at System.Web.Services.Protocols.SoapHttpClientProtocol.Invoke(String methodName, Object[] parameters)
ho letto in giro ed è perché il Large Object Heap è solo diventando troppo frammentato, quindi, anche la chiamata con un rapido controllo per StringBuilder.EnsureCapacity solo fa sì che il OutOfMemoryException deve essere lanciata prima (e poiché sto indovinando ciò che è necessario, potrebbe non aver bisogno di così tanto che il mio controllo sta causando più problemi di quello che sta risolvendo). Alcuni opinions sono che non c'è molto che posso fare al riguardo.
Alcune delle domande che mi sono chiesto:
- Usa meno memoria - Hai controllato la presenza di perdite? Sì. L'utilizzo della memoria va su e giù, ma non c'è una crescita fondamentale che garantisca che ciò accada. Alcune volte fallisce, ha avuto successo in quella fase in precedenza.
- trasferimento piccole quantità Non è un'opzione, questo è un servizio di terzi web su cui non ho alcun controllo (o almeno ci sarebbe voluto molto tempo per risolvere, nel frattempo ho ancora un problema)
- Puoi fare qualcosa al LOH per renderlo meno probabile che fallisca? ... ora questo è il corso più fruttuoso. È un processo a 32 bit (deve essere per vari motivi politici, tecnici e noiosi), ma normalmente ci sono centinaia di meg free (multipli dell'importo maggiore per il quale abbiamo visto fallimenti).
- È possibile monitorare il LOH? Uso perfmon Posso tenere traccia delle dimensioni degli heap, ma non penso che ci sia un modo per monitorare il più grande blocco di memoria contiguo disponibile.
La domanda è: qualche consiglio o suggerimento per le cose da provare?
Cambiare la rilegatura è una buona idea - darò una prova. Un riciclo a rotazione era la nostra ultima risorsa ... – Unsliced
siamo stati abbastanza fortunati da mitigare qualsiasi problema con l'elaborazione di documenti di grandi dimensioni attraverso entrambi i miglioramenti del codice (possediamo entrambi gli endpoint), o modifiche vincolanti, almeno per farci passare a un servizio di manutenzione periodica programmato (a causa di patch, rilascio di funzionalità, ecc.). L'idea di Steven di utilizzare windbg per l'analisi dell'heap può anche portare benefici. Prova http://blogs.msdn.com/tess/ e troverai ottime informazioni da Tess Ferrandez su come iniziare qui. Laboratori eccellenti! Buona fortuna! –