缓冲时来自服务器的WCF InsufficientMemoryException

时间:2013-06-12 21:56:32

标签: c# performance wcf memory

我在服务器上收到此错误。

  

System.InsufficientMemoryException,mscorlib,Version = 4.0.0.0,   Culture = neutral,PublicKeyToken = b77a5c561934e089

     

无法分配536870912字节的托管内存缓冲区。该   可用内存量可能很低。

这发生在最后一个语句 return myCollection 之后。当myCollection大约是45k项目时。

服务器配置:

<binding name="LargeTCPBinding"
         closeTimeout="00:30:00"
         openTimeout="00:30:00"
         receiveTimeout="01:00:00"
         sendTimeout="01:00:00"
         hostNameComparisonMode="StrongWildcard"
         maxBufferPoolSize="2147483647"
         maxReceivedMessageSize="2147483647"
         maxBufferSize="2147483647">
  <readerQuotas maxDepth="2147483647"
                maxStringContentLength="2147483647"
                maxArrayLength="2147483647"
                maxBytesPerRead="2147483647"
                maxNameTableCharCount="2147483647" />
  <security mode="Transport">
    <transport clientCredentialType="Windows" />
  </security>
</binding>

我做了一些基本的内存分析 GC.GetTotalMemory(false),将我的集合带入内存后的差异大约为170 MB。

在返回集合后发生异常(因此它似乎在缓冲发送期间发生)。

如果我将我的wcf连接配置切换为流式传输,则会修复异常,但调用时间从25秒到1:05分钟。

只是想了解这里发生了什么,因为那个集合并不是那么大。这是在WCF 4.0,64位cpu上运行。

1 个答案:

答案 0 :(得分:1)

这里重要的不是集合的SIZE,而是对象图的复杂性。如果您的集合包含具有许多字段和/或属性的引用类型,则这是一个更复杂/更深的图形。

在WCF向您发送响应之前,它必须将对象图序列化为二进制,通过网络发送,然后客户端对其进行反序列化。

Buffered意味着集合被序列化为内存中的结构,然后作为一个大块发送。流式表示集合在序列化时发送。

您的对象可能不大,但它的序列化表示可能非常庞大,仅仅是因为为您的数据和XML表示创建的SOAP信封等。

这就是Streamed解决您的问题的原因:缓冲无法一次在内存中以序列化形式表示整个对象图。