Утечка памяти в многопоточном приложении c # windows service - PullRequest
0 голосов
/ 26 августа 2009

У меня есть многопоточное приложение службы Windows для целей индексирования, которое имеет шесть потоков. Работает нормально, кроме утечки памяти. На самом деле, когда служба запущена, она потребляет 12 584 КБ памяти, через некоторое время она занимает 61 584 КБ. Но после завершения процесса индексации он не освобождает память. Мне нужно, чтобы он вернулся к своей прежней позиции после завершения индексации, то есть он должен взять память, с которой он начал, например. 12 584 КБ в этом случае. Я использовал сборщик мусора, но он не делает то, что я хочу.

Может кто-нибудь помочь мне?

Ответы [ 6 ]

4 голосов
/ 26 августа 2009

Первый совет - бросить в него профилировщик памяти. Я всегда был доволен ANTS-профайлером Red Gate , который поможет определить , какие объекты протекают, если таковые имеются.

Имейте в виду, что инициализация может происходить повсеместно в первый раз, поэтому вы, вероятно, захотите отслеживать ее с течением времени

2 голосов
/ 26 августа 2009

.NET не освобождает память, чтобы удовлетворить людей, смотрящих на диспетчер задач. Выделение памяти стоит дорого. CLR разработан так, чтобы делать это экономно и удерживать любую память, которую он выделяет, как можно дольше. Подумайте об этом так: какой смысл иметь 4 ГБ памяти, когда вы не используете половину этого объема?

Если вы на самом деле не ЗНАЕТЕ, что у вас есть утечка памяти (например, ваше приложение падает после двух дней безотказной работы), позвольте мне дать вам совет ... Закройте диспетчер задач. Не оптимизируйте для памяти, прежде чем вы знаете, что вам нужно. Расслабься, парень. Все хорошо.

1 голос
/ 26 августа 2009

61 МБ не звучит необычно. Вам нужно будет некоторое время позволить сервису работать и отслеживать использование памяти на предмет растущей тенденции. Если вы видите, что приложение выравнивается по определенному значению, вам, вероятно, не о чем беспокоиться.

0 голосов
/ 27 августа 2009

У меня была такая же проблема, пока я не изменил приложение с STA на MTA:

[MTAThread] общедоступная статическая пустота Main ()

вместо [STAThread] общедоступная статическая пустота Main ()

(я использовал ANTS-профилировщик Red Gate ...)

0 голосов
/ 26 августа 2009

Здесь я использую «log4net-1.2.10» для обработки исключений, «Lucene.net-2.1.0.3» для индексации, вот один класс «IndexWriter» для добавления документа в индекс или удаления документов из индекса. замок (объект) {
indexWriter.AddDocument (document); // объект indexWriter класса "IndexWriter".
}. Также мы используем очередь сообщений Microsoft для получения сообщений.

0 голосов
/ 26 августа 2009

Я полностью согласен с Уиллом - однако я предлагаю 2 небольших совета:

  1. Не используйте GC.Collect. Поверьте мне, вы не собираетесь улучшать алгоритм сборки мусора в CLR. Фактически объекты, которые готовы для сбора, но по какой-то причине не могут быть перемещены, будут перемещены на уровень 2, где им придется ждать еще дольше, прежде чем они будут собраны (что может привести к любой утечке, которая может быть хуже!)
  2. Повсюду проверяйте в своем коде, что вы создали какой-то тип потока (обычно MemoryStream) и убедитесь, что потоки закрываются должным образом (предпочтительно в блоке "finally")
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...