C#WCF – 客户端/服务器 – System.OutOfMemoryexception

问题。

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

脚本

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

摘要

  • 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 channelFactory = new DuplexChannelFactory( new InstanceContext(this), netTcpBinding, endpointAddress); proxy = channelFactory.CreateChannel(); 

我的问题

  • 如何防止客户端内存使用不断增长?
  • 如果我只发送对象的通用列表而不是可序列化的字典,那么客户端上的内存使用量是否会显着降低?
  • 我是否为这种实现正确设置了绑定配置?
  • 任何其他修复此内存问题的建议将不胜感激。

•如何防止客户端界面在内存使用方面呈指数级增长?

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

•如果我只发送对象的通用列表而不是可序列化的字典,那么客户端的内存使用量是否会低得多?

我对此表示怀疑。

•我是否已针对此类实施正确设置了绑定配置?

没有看到任何明显的问题

•非常感谢任何其他修复此内存问题的建议。

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

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

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

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

这里有一个很好的解释。