我有一個WCF客戶端應用程序,它使用一個非常大的響應(1GB)進行單個服務調用。我發現使這個服務調用使用了很多內存(500MB),即使響應對象不再被我的代碼引用,它似乎永遠不會被回收。如何清除我曾用過的一次WCF HTTP客戶端的PooledBufferManager?
我已經使用內存分析器來查看PooledBufferManager實例創建的字節數組中的大部分內存使用情況。
我正在使用的代理/客戶端已由Visual Studio自動生成,因此它是從System.ServiceModel.ClientBase派生的類< TChannel>。
我使用一個自定義的具有以下配置綁定:
<customBinding>
<binding name="foo"
closeTimeout="00:01:00"
openTimeout="00:01:00"
receiveTimeout="00:01:00"
sendTimeout="00:01:00">
<transactionFlow/>
<reliableSession ordered="true" inactivityTimeout="00:02:00"/>
<security authenticationMode="SecureConversation" messageSecurityVersion="WSSecurity11WSTrustFebruary2005WSSecureConversationFebruary2005WSSecurityPolicy11BasicSecurityProfile10">
<secureConversationBootstrap messageSecurityVersion="WSSecurity11WSTrustFebruary2005WSSecureConversationFebruary2005WSSecurityPolicy11BasicSecurityProfile10">
<localClientSettings maxClockSkew="23:59:00"/>
</secureConversationBootstrap>
<localClientSettings maxClockSkew="23:59:00"/>
</security>
<mtomMessageEncoding>
<readerQuotas maxDepth="2147483647" maxStringContentLength="2147483647" maxArrayLength="2147483647" maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647"/>
</mtomMessageEncoding>
<httpTransport maxBufferPoolSize="2147483647" maxBufferSize="2147483647" maxReceivedMessageSize="2147483647"/>
</binding>
</customBinding>
周圍的人閱讀談論了幾個解決方案,以這樣的:
- 切換到流媒體的反應模式,而不是緩衝,但我相信這是針對TCP WCF連接的,而不是像我的那樣的HTTP。
- 將maxBufferPoolSize設置爲零以禁用緩衝池。在httpTransport元素中設置它對我來說似乎沒有任何影響。
- 在適當的BufferManager/PooledBufferManager上調用Clear()。我無法從ClientBase派生實例的上下文中找到要調用此對象的對象。我確實設法使用調試器找到合適的PooledBufferManager實例,並深入挖掘私有innerChannelFactory字段中的許多級別,但這對於從代碼與其進行交互沒有用處。
- 手動調用GC.Collect()似乎回收大約50MB的優秀500MB。
回收儘可能多的這種一次性服務呼叫使用的內存的最佳方法是什麼?我正在接受一個專門過程中的服務呼叫,我可以在這一點上殺死回收內存。