Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Общие вопросы по .NET и C# > Менеджмент и Освобождение Памяти


Автор: bytex2 26.5.2006, 15:31
Всем привет,

Написал многопоточную парсилку HTML страниц.

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

С чем это может быть связанно ?

Глядя на график память/время, видно что память иногда освобождается, но тут же занимается еще больше, ну и своп растет сильно.
Иногда прога начинает занимать до 600Мб в памяти, и еще не меньше в Swap.

Как это лечится ?  smile 

 

Автор: Дрон 26.5.2006, 15:37
Фигасе...

А вообще мы тут не телепаты smile
Скорее всего что-то не так в самой программе. Например, ты случаем разных нехороших операций с большими (> 1000 символов) строками не делаешь?

Для начала же попробуй через некоторые промежутки времени вызывать GC.Collect(); -- вдруг поможет smile 

Автор: Exception 26.5.2006, 15:39
Если делаешь много операций со строками, используй класс StringBuilder. 

Автор: bytex2 26.5.2006, 15:51
Дрон

Извиняюсь за невнятный вопрос smile Дело в том что я написал в начале свое творение на Delphi, но потом решил
попробовать реализовать его на C# так как в C# есть автоматическая сборка мусора.

Как часто надо использовать GC.Collect() ?

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

Не мог бы ты подсказать что тут можно оптимизировать ? Заранее спасибо smile

Код

            public IHTMLDocument2 getHtmlPage(String url)
            {
                ServicePointManager.DefaultConnectionLimit = 20;
                IWebRequestCreate webRequestCreate = new CompressibleHttpRequestCreator();
                CompressibleHttpWebRequest Req = (CompressibleHttpWebRequest)webRequestCreate.Create(new Uri(url));
                Req.AcceptEncodings = AcceptEncodings.GZip;
                Req.Timeout=timeout * 1000;
                CompressibleHttpWebResponse Resp = (CompressibleHttpWebResponse)Req.GetResponse();
                StreamReader Reader = new StreamReader(Resp.GetResponseStream());
                string Body = Reader.ReadToEnd();

                ActivityFlag = true;
                Resp.Close();

                mshtml.HTMLDocument Doc1 = new mshtml.HTMLDocument();
                IHTMLDocument2 Doc2 = (IHTMLDocument2)Doc1;
                Doc2.write(Body);
                Doc2.close();

                return Doc2;
            }


Добавлено @ 15:53 
Exception

В том то все и дело что я не делаю массовых операций со строками.
Все что я делаю, это скачиваю страницу, анализирую ее на предмет присутствия там своих меток,
кладу урл в ArrayList и скачиваю новую страницу.  

Автор: Exception 26.5.2006, 15:54
Модератор: используйте кнопку "Код"! 

Автор: Дрон 26.5.2006, 16:21
Цитата(bytex2 @  26.5.2006,  16:51 Найти цитируемый пост)
Как часто надо использовать GC.Collect() ?

Не слишком часто. Более конкретных рекомендаций нет. Надо самому экспериментировать.

Есть предположение, что mshtml.HTMLDocument(); съедает много памяти. Но я с ним не работал -- ничего сказать не могу. Для начала проверь, есть ли у него метод Dispose() и если есть то вызывай его, когда он тебе становится не нужен. Кстати, то же самое и для других объектов (Req, Reader и т.д.).  

Автор: bytex2 26.5.2006, 17:09
Дрон

А может помочь если в конце String Body = null делать ?
 

Автор: Дрон 26.5.2006, 17:43
Цитата(bytex2 @  26.5.2006,  18:09 Найти цитируемый пост)
А может помочь если в конце String Body = null делать ?

Нет. Она и так при выходе из метода за пределы видимости уходит. 

Автор: ivashkanet 26.5.2006, 20:50
Цитата(Дрон @  26.5.2006,  16:21 Найти цитируемый пост)
Dispose()

Вместо вызова Dispose() лучше поьзоваться конструкцией using
Код

using (mshtml.HTMLDocument Doc1 = new mshtml.HTMLDocument())
{
}

Она сама, по ее завершению, уничтожит объект Doc1, вызвав его метод finalize(). 
Аналогично с остальными  smile 
P.S. По поводу GC (Garbige Collector) он работает с особенностями: все объекты пережившие две! (по умолчанию) сборки мусора не удалятся никогда  smile 
Можно вручную изменить этот параметр: GC.MaxGeneration
Плюс к этому если у класса есть деструктор, то при первой сборке мусора он вызывается, но объект уничтожается только после следующей сборки. Почти 100% кандидат в "бессмертные"  smile 
P.P.S. Где то здесь Void постил ссылку на инфу по этому поводу. ИМХО в теме "Мои ламерские вопросы по C#" тов. Сарт-а  smile 
P.P.P.S 
Цитата(bytex2 @  26.5.2006,  15:51 Найти цитируемый пост)
анализирую ее на предмет присутствия там своих меток

А где ты это делаешь? В 
Цитата(bytex2 @  26.5.2006,  15:51 Найти цитируемый пост)
IHTMLDocument2 Doc2 = (IHTMLDocument2)Doc1;
 или 
Цитата(bytex2 @  26.5.2006,  15:51 Найти цитируемый пост)
Doc2.write(Body);
 Больше я подозрительных строчек не нашел  smile 
 

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)