我在服务器上收到此错误。
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上运行。
答案 0 :(得分:1)
这里重要的不是集合的SIZE,而是对象图的复杂性。如果您的集合包含具有许多字段和/或属性的引用类型,则这是一个更复杂/更深的图形。
在WCF向您发送响应之前,它必须将对象图序列化为二进制,通过网络发送,然后客户端对其进行反序列化。
Buffered意味着集合被序列化为内存中的结构,然后作为一个大块发送。流式表示集合在序列化时发送。
您的对象可能不大,但它的序列化表示可能非常庞大,仅仅是因为为您的数据和XML表示创建的SOAP信封等。
这就是Streamed解决您的问题的原因:缓冲无法一次在内存中以序列化形式表示整个对象图。