Re: OutOfMemoryException при работе с большими строками
От: gonia Казахстан  
Дата: 04.10.11 12:07
Оценка: 3 (1) +1
Здравствуйте, Mazenrab:

1. попробуйте начинать писать документ клиенту в Web Response Stream еще до того как полностью сформируете файл. То есть итерации вашего цикла должны работать со стримом вместо StringBuilder'а.
2. попробуйте сначала все записать во временный файл опять же через Стрим, а после перенаправьте файл стрим в стрим ответа клиенту.
OutOfMemoryException при работе с большими строками
От: Mazenrab Россия http://www.electrica.ru
Дата: 04.10.11 08:12
Оценка:
Всем привет.
Столкнулся с такой ситуацией. На сайте на лету генерятся вордовские документы в формате XML и отдаются клиенту в браузер.

В нижеприведенном отрывке кода в XML-шаблон документа по меткам вставляются изображения.
И все бы ничего, но при достаточно больших изображениях получаем достаточно большие строки.
Например у меня тестовый документ потянул приблизительно на 75Mb.
При таких объемах получаю почти гарантированно OutOfMemoryException.
Собственно вопрос как с этим бороться? Вроде все что мог на StringBuilder перевел.

И второй вопрос. Заметил что на серваке вероятность получения OutOfMemoryException возрастает в зависимости от количества одновременных запросов на генерацию документа. И совершенно точно что физически на сервере память имеется и ее много. В пуле приложения ограничений на память не наблюдаю. Что это может значить?

            string fileName = String.Format("файл_{0}.doc", pOrderId);
            StringBuilder strBody = new StringBuilder();
            try
            {               
               ... 
                strBody.Append(_str_val);

                foreach (var op in query)
                {
                    int pictId = op.Field<int>("pict-id");
                    byte[] pictVal = op.Field<byte[]>("pict-val");
                    string pictType = op.Field<string>("pict-type");
                    
                    using (MemoryStream ms = new MemoryStream(pictVal))
                    {
                        using (System.Drawing.Image img = System.Drawing.Image.FromStream(ms))
                        {
                            OfficePictureWriter opw = OfficePictureWriter.Create(img, "", String.Format("{0}", pictId));
                            string pict = opw.ToString();
                            string mark = String.Format("#{0}#", pictId);
                            strBody.Replace( mark, pict );
                        }
                    }
                }
                Response.AppendHeader("Content-Type", "application/msword");
                Response.AppendHeader("Content-disposition", "attachment; filename=" + fileName);
                Response.Write(strBody.ToString());
                Response.End();
Re: OutOfMemoryException при работе с большими строками
От: Аноним  
Дата: 04.10.11 10:39
Оценка:
Здравствуйте, Mazenrab, Вы писали:

раньше гдето было, что юнет процесс не мог отжырать более 60% памяти иначе пул падал — нужно поукопаться в настройках по поводу увеличения этого лимита
Re[2]: OutOfMemoryException при работе с большими строками
От: Mazenrab Россия http://www.electrica.ru
Дата: 04.10.11 11:14
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Здравствуйте, Mazenrab, Вы писали:


А>раньше гдето было, что юнет процесс не мог отжырать более 60% памяти иначе пул падал — нужно поукопаться в настройках по поводу увеличения этого лимита


Спасибо, я попробовал лимит в гиг выдать пулу, не помогает, диспетчер процессов утверждает при этом, что в пике пул отжирал около 500-600 метров.
Re[2]: OutOfMemoryException при работе с большими строками
От: Mazenrab Россия http://www.electrica.ru
Дата: 04.10.11 13:01
Оценка:
Здравствуйте, gonia, Вы писали:

G>Здравствуйте, Mazenrab:


G>1. попробуйте начинать писать документ клиенту в Web Response Stream еще до того как полностью сформируете файл. То есть итерации вашего цикла должны работать со стримом вместо StringBuilder'а.

G>2. попробуйте сначала все записать во временный файл опять же через Стрим, а после перенаправьте файл стрим в стрим ответа клиенту.

Спасибо, попробую.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.