Tag: buffer manager

如何防止WCF客户端应用程序中的BufferManager / PooledBufferManager浪费内存?

分析一个WCF客户端应用程序(我没有写,但仍然不太了解)通过SOAP与一堆服务进行通信,运行几天后会抛出一个OutOfMemoryException,我发现.net的PooledBufferManager将会永远不会释放未使用的缓冲区,即使应用程序内存不足,也会导致OOME。 这当然符合规范: http : //msdn.microsoft.com/en-us/library/ms405814.aspx 当垃圾收集回收缓冲池时,池及其缓冲区被销毁。 请随意回答下面的一个问题,因为我有一堆问题,一些更一般的问题,以及一些特定于我们的应用程序使用BufferManager。 首先是关于(默认的Pooled)BufferManager的几个一般性问题: 1)在我们有GC的环境中,为什么我们需要一个可以保留未使用内存的BufferManager,即使它导致OOME? 我知道,有BufferManager.Clear(),您可以使用它来手动删除所有缓冲区 – 如果您有权访问BufferManager,即。 进一步了解为什么我似乎无法访问。 2)尽管MS声称“​​这个过程比每次需要使用一个缓冲区创建和销毁缓冲区要快得多。”,他们不应该把它留给GC(例如它的LOH)并优化GC而不是? 3)当做一个BufferManager.Take(33 * 1024 * 1024)时,我会得到一个64M的缓冲区,因为PooledBufferManager将缓存该缓冲区以供以后重用,这可能 – 好吧,在我的情况下它不是,因此它是纯粹浪费记忆 – 比如34M,或50M,或64M,是需要的。 因此创建一个可能非常浪费的BufferManager是明智的,HttpsChannelFactory使用(默认情况下,我假设)? 我没有看到内存分配的性能如何重要,特别是当我们讨论WCF和网络服务时,应用程序将每隔10秒TOPS,通常更多秒甚至几分钟。 现在有一些更具体的问题与我们的应用程序使用BufferManagers有关。 该应用程序连接到几个不同的WCF服务。 对于它们中的每一个,我们为http连接维护一个连接池,因为连接可能同时发生。 检查一个堆转储中的单个最大对象,一个64M字节数组,在初始化时只在我们的应用程序中使用过一次,之后不需要,因为来自服务的响应仅在初始化时才很大,即btw。 对于我使用过的许多应用程序来说都是典型的,即使这可能会受到优化(缓存到磁盘等)。 WinDbg中的GC根分析产生以下结果(我将我们的专有类的名称清理为’MyServiceX’等): 0:000:x86> !gcroot -nostacks 193e1000 DOMAIN(00B8CCD0):HANDLE(Pinned):4d1330:Root:0e5b9c50(System.Object[])-> 035064f0(MyServiceManager)-> 0382191c(MyHttpConnectionPool`1[[MyServiceX, MyLib]])-> 03821988(System.Collections.Generic.Queue`1[[MyServiceX, MyLib]])-> 038219a8(System.Object[])-> 039c05b4(System.Runtime.Remoting.Proxies.__TransparentProxy)-> 039c0578(System.ServiceModel.Channels.ServiceChannelProxy)-> 039c0494(System.ServiceModel.Channels.ServiceChannel)-> 039bee30(System.ServiceModel.Channels.ServiceChannelFactory+ServiceChannelFactoryOverRequest)-> 039beea4(System.ServiceModel.Channels.HttpsChannelFactory)-> 039bf2c0(System.ServiceModel.Channels.BufferManager+PooledBufferManager)-> 039c02f4(System.Object[])-> 039bff24(System.ServiceModel.Channels.BufferManager+PooledBufferManager+BufferPool)-> 039bff44(System.ServiceModel.SynchronizedPool`1[[System.Byte[], mscorlib]])-> 039bffa0(System.ServiceModel.SynchronizedPool`1+GlobalPool[[System.Byte[], mscorlib]])-> 039bffb0(System.Collections.Generic.Stack`1[[System.Byte[], […]