Утечки памяти службы WCF - PullRequest
6 голосов
/ 12 мая 2010

У меня очень маленькая служба wcf, размещенная в консольном приложении.

[ServiceContract]
public interface IService1
{
    [OperationContract]
    void DoService();
}

[ServiceBehavior(InstanceContextMode=InstanceContextMode.PerCall)]
public class Service1 : IService1
{
    public void DoService()
    {

    }
}

и его называют

using (ServiceReference1.Service1Client client = new ServiceReference1.Service1Client())
{
    client.DoService(new DoServiceRequest());
    client.Close();
} 

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

Задача

Теперь, когда я выполнил приведенный выше код клиента в цикле 1000, я обнаружил большую разницу между счетчиками производительности «Все байты кучи» и «Приватные байты» (я использовал .net memory profiler). После расследования я обнаружил, что некоторые объекты не были правильно утилизированы Ниже приведен список этих объектов (найдено 1000 нераспределенных экземпляров -> равно числу вызовов клиента)

(пространство имен для всех них - System.ServiceModel.Channels)

HttpOutput.ListenerResponseHttpOutput.ListenerResponseOutputStream
BodyWriterMessage
BufferedMessage
HttpRequestContext.ListenerHttpContext.ListenerContextHttpInput.ListenerContextInputStream
HttpRequestContext.ListenerHttpContext 

Вопросы Почему у нас много неразмещенных объектов и как ими управлять.

Пожалуйста, помогите

Ответы [ 3 ]

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

Вы запрашиваете новый экземпляр для каждого вызова (InstanceContextMode = InstanceContextMode.PerCall). Если в вызовах 1000 GC не происходит, то экземпляры службы будут отменены. WCF требует от вас реализации IDisposable

Из MSDN: Откройте для себя мощные методы управления экземплярами для разработки приложений WCF

Услуги за звонок Службы для вызовов - это режим создания по умолчанию Windows Communication Foundation. Когда тип службы настроен для активации каждого вызова, экземпляр службы, объект общеязыковой среды выполнения (CLR), существует только во время выполнения вызова клиента. Каждый клиентский запрос получает новый выделенный экземпляр службы. На рисунке 2 показано, как работает активация одним вызовом.

Рис. 2. Инстанцирование по вызову http://i.msdn.microsoft.com/cc163590.fig02(en-us).gif

  1. Клиент вызывает прокси и прокси переадресует вызов сервис.
  2. Windows Communication Foundation создает службу экземпляр и вызывает на нем метод.
  3. После возврата вызова метода, если объект реализует IDisposable, затем Windows Связь Фонд звонков IDisposable. Укажите на нем.
1 голос
/ 16 февраля 2012

Вы случайно не включили счетчики производительности? Как ниже?

<system.serviceModel>
  <diagnostics performanceCounters="All" />
  ..
</system.serviceModel>

В параграфе «Увеличение объема памяти для счетчиков производительности», по этой ссылке: http://msdn.microsoft.com/en-us/library/ms735098.aspx

есть упоминание о "мошенническом" числе частных байтов, когда счетчики производительности WCF включены. Замена его на ServiceOnly или его полное отключение (Off) может помочь.

0 голосов
/ 14 июня 2014

Я нашел решение еще в 2010 году, но забыл опубликовать его. Я на самом деле потерял точный трек, но я помню, что это ошибка библиотеки .Net, о которой было сообщено в Microsoft и которая была им подтверждена. У меня нет этой ссылки, но я бы опубликовал ее, как только смогу ее найти. В любом случае Microsoft исправила эту проблему в .net 4.0, и это точное решение, которому я следовал, я знаю, что для некоторых из вас это может оказаться невозможным из-за того, что изменение серверной среды иногда не в ваших руках.

...