очень большая строка в памяти - PullRequest
9 голосов
/ 17 мая 2010

Я пишу программу для форматирования 100-секундных данных MB String (около гигабайта) в xml == И я должен вернуть ее в ответ на запрос HTTP (GET).

Я использую StringWriter / XmlWriter для создания XML-записей в цикле и возврата

using (StringWriter writer = new StringWriter())
using (writer = XmlWriter.Create(writer, settings)) //where settings are the xml props

writer.ToString() 

во время тестирования я видел несколько - исключений из памяти - и совершенно не знал, как найти решение? Ребята, есть ли у вас какие-либо предложения по оптимизации доставки ответа по памяти?

существует ли эффективный для памяти способ кодирования данных? или, может быть, чанки данных - Я просто не могу придумать, как вернуть его, не собрав все это в один ОГРОМНЫЙ строковый объект

спасибо

- несколько уточнений - это приложение asp .net webservices по гигабитному каналу Ethernet, как заметил Джош. Я не очень знаком с этим, так что все еще немного кривой обучения.

Я использую XMLWriter для создания XML и создания из него строки, используя String

некоторые характеристики - Размер xml ответа = около 385 мегабайт (мой размер данных очень быстро увеличится до гораздо большего)

размер строкового объекта, рассчитанный профилировщиком памяти = достиг пика в 605 МБ

и спасибо всем, кто откликнулся ...

Ответы [ 6 ]

5 голосов
/ 17 мая 2010

Используйте XmlTextWriter, обернутый вокруг Reponse.OutputStream, чтобы отправить XML клиенту и периодически сбрасывать ответ. Таким образом, вам никогда не нужно иметь больше, чем несколько мегабайт в памяти одновременно (по крайней мере, для отправки клиенту).

4 голосов
/ 17 мая 2010

Разве вы не можете просто передать ответ клиенту? XmlWriter не требует, чтобы его основной поток был буферизован в памяти. Если это ASP.NET, вы можете использовать Response.OutputStream или, если это WCF, вы можете использовать потоковую передачу ответов .

1 голос
/ 10 сентября 2014

Была похожая проблема, надеюсь, это кому-нибудь поможет. Мой начальный код был:

var serializer = new XmlSerializer(type);
string xmlString;

using (var writer = new StringWriter())
{
    serializer.Serialize(writer, objectData, sn); // OutOfMemoryException here
    xmlString = writer.ToString();
}

В итоге я заменил StringWriter на MemoryStream, и это решило мою проблему

using (var mem = new MemoryStream())
{
    serializer.Serialize(mem, objectData, sn);
    xmlString = Encoding.UTF8.GetString(mem.ToArray());
}
1 голос
/ 17 мая 2010

Вы не должны создавать XML, используя строковые манипуляции.

Вместо этого вы должны использовать классы XmlTextWriter, XmlDocument или (в .Net 3.5) XElement для построения дерева XML в памяти, а затем записать его непосредственно в Response.OutputStream, используя XmlTextWriter.

Запись непосредственно в XmlTextWriter, который включает Response.OutputStream, будет наиболее эффективной (у вас никогда не будет целого дерева элементов в памяти сразу), но будет несколько сложнее.

Делая это таким образом, вы никогда не будете иметь единственную строку (или массив), содержащую весь объект, и, таким образом, должны избегать OutOfMemoryExceptions.

1 голос
/ 17 мая 2010

HTTP получить за 1 гиг? это много! Возможно, вам следует пересмотреть. По крайней мере, gziping вывод может помочь.

0 голосов
/ 17 мая 2010

Вам нужно будет возвращать каждую запись (или небольшую группу записей) в их собственных GET.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...