Как к maxmise самый большой непрерывный блок памяти в "Куче" для больших объектов

Ситуация состоит в том, что я выполняю вызов WCF к удаленному серверу, который является возвратами XML-документ как строка.

Большую часть времени это возвращаемое значение является несколькими K, иногда несколькими дюжинами K, достаточно редко несколько сотен K, но очень редко это могли быть несколько мегабайтов (первая проблема состоит в том, что нет никакого способа для меня знать).

Именно эти редкие случаи вызывают горе. Я получаю отслеживание стека, которое запускается:

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)

Я читал вокруг, и это - потому что "Куча" для больших объектов просто становится слишком фрагментированной, поэтому так предшествуя вызову с быстрой проверкой к StringBuilder. Правые дела EnsureCapacity OutOfMemoryException, который будет брошен ранее (и потому что я предполагаю то, что необходимо, возможно, не на самом деле требовалось бы так много так моя проверка, вызывает больше проблем, чем он, решают). Некоторые мнения - то, что нет очень, я могу делать с этим.

Некоторые вопросы я спросил меня:

  • Используйте меньше памяти - Вы проверили на утечки? Да. Использование памяти идет вверх и вниз, но нет никакого фундаментального роста, который гарантирует это для случая. Некоторые времена, которые это приводит к сбою, это успешно выполнилось на том этапе ранее.
  • Переведите меньшие суммы Не опция, это - сторонний веб-сервис, над которым я не имею никакого контроля (или по крайней мере требовалось бы много времени для разрешения, тем временем у меня все еще есть проблема),
  • Можно ли сделать что-то к LOH для создания его менее вероятно для сбоя?... теперь это - самый плодотворный курс. Это - 32-разрядный процесс (это должно быть по различным политическим, техническим и скучным причинам), но обычно существуют сотни свободного meg (кратные числа самой большой суммы, для которой мы видели отказы).
  • Мы можем контролировать LOH? Используя perfmon я могу отследить размер "кучи", но я не думаю, что существует способ контролировать самый большой доступный непрерывный блок памяти.

Вопрос: совет или предложения для вещей попробовать?

5
задан Unsliced 22 April 2010 в 11:44
поделиться

2 ответа

Вы можете просмотреть свойство TransferMode вашей привязки, чтобы узнать, соответствуете ли вы требованиям для изменения его значения по умолчанию «Буферизованный» на « Streamed "или" StreamedResponse ".

Также просмотрите значения для maxBufferPoolSize и maxBufferSize .Увеличение размера используемых внутренних буферов может помочь в использовании памяти, особенно при обработке больших сообщений.

maxReceivedMessageSize также, вероятно, уже установлен, если вы получаете большие сообщения, но я бы также просмотрел это значение.

Я видел одно из приведенных выше значений: если вы превышаете порог, выдает непонятное сообщение, связанное с памятью. Первоначальное исключение было фактически скрыто сообщением, которое появилось в моем приложении. Включение трассировки WCF помогло диагностировать проблему и увидеть настоящую ошибку - мне нужно было увеличить значение одного или нескольких свойств привязки, указанных выше.

Я не почувствовал привязку вашего использования из вашего сообщения, но я считаю, что эти настройки являются общими для основных. Посмотрите, например, документацию MSDN на basicHttpBinding .

Если это действительно LOH-фрагментация, то после того, как усилия по настройке исчерпаны, с этим ничего не поделаешь. Для смягчения последствий может потребоваться непрерывная перезагрузка приложения (я ненавижу рекомендовать это), но если вы исчерпали другие усилия, это может остаться у вас.

5
ответ дан 14 December 2019 в 01:04
поделиться

Я думаю, ваша проблема может быть утечкой сборки, вызванной использованием XmlSerializer, а не одним из двух конструкторов, как указано в этой статье MSDN :

Для повышения производительности XML инфраструктура сериализации динамически генерирует сборки для сериализовать и десериализовать указанные типы. Инфраструктура находит и повторно использует эти сборки. Это поведение возникает только при использовании следующих конструкторы:

XmlSerializer.XmlSerializer (Тип)

XmlSerializer.XmlSerializer (Тип, String)

Если вы используете любой другой конструкторы, несколько версий генерируются одинаковые сборки и никогда выгружен, , что приводит к памяти течь и плохая работа.

Прекрасно, да. Ответ заключается в том, чтобы кэшировать ваш XmlSerializer (при условии, что вы его даже создаете).

Чтобы понять это, вам нужно сделать то, что Тесс говорит вам делать. Она чертов гений.

1
ответ дан 14 December 2019 в 01:04
поделиться
Другие вопросы по тегам:

Похожие вопросы: