C # WCF - клиент / сервер - исключение System.OutOfMemory - PullRequest
3 голосов
/ 08 ноября 2010

Проблема.

  • Клиентское / серверное приложение C # WCF, использующее привязку Net TCP (шаблон издателя / подписчика).
  • На стороне клиента происходит сбой при OutOfMemoryException.
  • Когда я запускаю диспетчер задач вместе с клиентом, я вижу увеличение столбца «Использование памяти» до сбоя приложения.
  • Предполагается, что несколько экземпляров клиента будут запущены на разных компьютерах.

Сценарий

  • У меня есть приложение клиент / сервер.
  • Шаблон проектирования издателя / подписчика.
  • На стороне сервера есть6 словарей, составляющих кэш, каждый из которых содержит пользовательский объект в качестве значения.
  • Каждый набор значений словаря обновляется каждые 5 секунд как часть цикла while.
  • В концеиз 5-секундного цикла 6 словарей добавляются к объекту обработки данных, каждый в качестве отдельного элемента данных.
  • Затем объект контракта данных отправляется по проводной связи клиенту, где есть еще 6 элементовionaries.
  • Затем я перебираю каждый словарь контракта данных и добавляю или обновляю содержимое его эквивалента на стороне клиента, в зависимости от того, существуют ли уже значения или нет.

Сводка

  • 6 словарей на стороне сервера.
  • 6 сериализуемых словарей в контракте данных.
  • 6 привязываемых словарей на стороне клиента.
  • WCF с использованием Net TCP Binding для передачи данных по проводам.

Спецификация

  • C # .Net 3.5
  • На стороне клиента с использованием одной формы DevExpress и 9Виды сетки DX и элементы управления вкладками.
  • Большинство пользовательских объектов связываются со словарем «субактивов».- Я использовал привязываемый словарь для этого свойства, которое, я думаю, создает накладные расходы, когда у вас есть несколько сотен объектов (хотя я не думаю, что использование сериализуемого словаря вместо этого будет иметь большое значение, так как они оба содержат один и тот же код для сериализации).
  • Привязки с обеих сторон программно создаются один раз при запуске и содержат одинаковые настройки (см. Ниже).

    NetTcpBinding netTcpBinding = new NetTcpBinding(SecurityMode.None);
    
    EndpointAddress endpointAddress = new EndpointAddress(EndpoindAddress);
    InstanceContext context = new InstanceContext(callbackinstance);
    
    netTcpBinding.MaxConnections = 5;
    netTcpBinding.MaxBufferSize = 2147483647;
    netTcpBinding.MaxBufferPoolSize = 2147483647;
    netTcpBinding.MaxReceivedMessageSize = 2147483647;
    netTcpBinding.ReceiveTimeout = TimeSpan.MaxValue;
    netTcpBinding.CloseTimeout = TimeSpan.MaxValue;
    netTcpBinding.TransferMode = TransferMode.Buffered;
    netTcpBinding.ListenBacklog = 5;
    
    DuplexChannelFactory<ISubscription> channelFactory =
       new DuplexChannelFactory<ISubscription>(
              new InstanceContext(this), 
              netTcpBinding,
              endpointAddress);
    
    proxy = channelFactory.CreateChannel();
    

Мои вопросы

  • Как я могу предотвратить постоянное увеличение использования памяти клиентом?
  • Было бы значительно меньше использования памяти на клиенте, если бы я отправлял только общие списки объектов в отличие от сериализуемых словарей?
  • Правильно ли я настроил свои конфигурации привязки для такого рода реализации?
  • Будем весьма благодарны за любые другие предложения по устранению этой проблемы с памятью.

Ответы [ 3 ]

1 голос
/ 10 ноября 2010

• Как я могу предотвратить клиентский интерфейс только растет экспоненциально с точки зрения памяти использование

Эм, это не растет в геометрической прогрессии, но убедитесь, что у вас нет случайных ссылок, в частности ищите события и лямбды, которые могут иметь ссылки на ваши случайные объекты

• Будет ли использование памяти на на стороне клиента будет намного ниже, если я отправлю только общие списки объектов как в отличие от сериализуемых словарей?

Я сомневаюсь в этом.

• Я установил привязку правильные конфигурации для этого вида реализации?

Не вижу никаких очевидных проблем с ними

• Любые другие предложения по исправлению проблема с памятью будет сильно оценили.

Посмотрите Windbg, для правильного обучения требуется время, но это может помочь вам увидеть, что имеет отношение к чему ... это может быть не то, что вы ожидаете

0 голосов
/ 04 апреля 2012

Увеличение MaxBufferPoolSize до 2 ГБ (netTcpBinding.MaxBufferPoolSize = 2147483647;) не является мудрым решением, если у вас нет свободной памяти.

WCF будет продолжать накапливать буферы, и вы можете получить OutOfMemoryException.

Вот хорошее объяснение здесь .

0 голосов
/ 10 ноября 2010

Вы убедитесь, что у вас есть только один ServiceChannelFactory и что каналы WCF открываются как можно позже, закрываются как можно раньше?

...