C#WCF - 客户端/服务器 - System.OutOfMemory异常

时间:2010-11-08 10:16:39

标签: c# wcf out-of-memory

问题。

  • 使用Net TCP绑定的C#WCF客户端/服务器应用程序(发布者/订阅者模式)。
  • 客户端不断崩溃OutOfMemoryException
  • 当我与客户端一起运行任务管理器时,我可以看到“内存使用情况”列增加,直到应用程序崩溃。
  • 意图是让客户端的多个实例在不同的计算机上运行。

方案

  • 我有一个客户端/服务器应用程序。
  • 发布者/订阅者设计模式。
  • 在服务器端,有6个词典构成一个缓存,每个词典都包含一个自定义对象作为值。
  • 每组字典值每5秒更新一次,作为while循环的一部分。
  • 在5秒循环结束时,6个字典被添加到datacontract对象,每个字体作为不同的数据成员。
  • 然后,数据合同对象通过网络发送到客户端,其中还有6个字典。
  • 然后我遍历每个数据合同字典,并添加或更新它的客户端等效字典的内容,具体取决于值是否已存在。

摘要

  • 6个字典服务器端。
  • 数据合同中的6个可序列化词典。
  • 6个可绑定字典客户端。
  • WCF使用Net TCP绑定通过网络传输数据。

规范

  • 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 个答案:

答案 0 :(得分:1)

  

•我该如何防止   刚刚成长的客户端界面   在记忆方面呈指数级增长   使用

嗯,它没有成倍增长,但要确保你没有杂散的引用, 特别是寻找可能引用您的迷路对象的事件和lambda

  

•内存使用量是否会在   如果我发送,客户端要低得多   只有对象的通用列表   反对可序列化的词典?

我对此表示怀疑。

  

•我是否设置了绑定   这种配置正确   实施?

不要看到任何明显的问题

  

•解决此问题的任何其他建议   记忆问题会很大   赞赏。

查看Windbg,它需要时间来正确学习,但它可以帮助你看到什么引用了什么......它可能不是你所期望的

答案 1 :(得分:0)

您是否确保只有一个ServiceChannelFactory,并且尽可能早地尽快关闭WCF频道?

答案 2 :(得分:0)

将MaxBufferPoolSize最大化为2 GB(netTcpBinding.MaxBufferPoolSize = 2147483647;)并不是明智的决定,除非你有足够的RAM。

WCF将继续累积缓冲区,您可能会收到OutOfMemoryException

有一个很好的解释here