问题标签 [buffer-manager]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
c# - System.ServiceModel.Channels.BufferManager 是线程安全的吗?
我通过BufferManager.CreateBufferManager
. 这个新创建BufferManager
的被多个线程使用。
我应该使用lock
withTakeBuffer()
还是ReturnBuffer()
它在设计上是线程安全的?
c# - 如何防止 WCF 客户端应用程序中的 BufferManager / PooledBufferManager 浪费内存?
分析一个通过 SOAP 与一堆服务对话的 WCF 客户端应用程序(我没有编写,仍然不太了解),运行几天后会抛出 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 字节的数组,它在初始化时只在我们的应用程序中使用过一次,之后就不需要了,因为服务的响应只有在初始化时才那么大,顺便说一句。对于我使用过的许多应用程序来说是典型的,即使这可能会受到优化(缓存到磁盘等)。WinDbg 中的 GC 根分析产生以下结果(我将我们专有类的名称清理为“MyServiceX”等):
查看由 BufferManager 管理的其他字节数组的 gc 根显示其他服务(不是“MyServiceX”)具有不同的 BufferPool 实例,因此每个服务都在浪费自己的内存,他们甚至没有共享浪费。
4)我们在这里做错了吗?我无论如何都不是 WCF 专家,所以我们可以让各种 HttpsChannelFactory 实例都使用相同的 BufferManager 吗?
5)或者甚至更好,我们是否可以告诉所有 HttpsChannelFactory 实例根本不要使用 BufferManagers 并要求 GC 完成它该死的工作,即“管理内存”?
6)如果问题 4) 和 5) 无法回答,我是否可以访问所有 HttpsChannelFactory 实例的 BufferManager 并手动调用它们 .Clear() - 这远非最佳解决方案,但它已经有所帮助,就我而言,它不仅会释放上述 64M,而且会在一个服务实例中释放 64M + 32M + 16M + 8M + 4M + 2M!因此,仅此一项就可以使我的应用程序持续更长时间而不会遇到内存问题(不,除了 BufferManager 之外,我们没有内存泄漏问题,尽管我们确实消耗了大量内存并在整个过程中积累了大量数据很多天,但这不是这里的问题)
.net - BufferManager 的真实用例
试图找出 OutOfMemoryException 的底部,我发现 WCF 的缓冲 TransferMode 使用的 .net 的BufferManagers负责浪费数百兆字节(请参阅问题和我自己的关于如何在我的 WCF 客户端中防止 BufferManager / PooledBufferManager的答案应用程序浪费内存?有关详细信息以及如何通过简单地从“缓冲”切换到“流式”来修复它)。
撇开 WCF 不谈,BufferManagers 被发明为比您通常所做的更好的替代方案:在需要时简单地分配字节数组,并依靠 GC 清理它们并在引用超出范围时回收它们。
所以我的问题是:有没有人在现实世界的应用程序中使用过 BufferManagers,以便在性能方面产生显着差异,以证明必须手动 .Clear() BufferManager(如果有必要的话)带来的不便?
如果是这样,是否可以仅手动创建一个单字节缓冲区并保留对它的引用并不能解决该特定问题?
c# - 如何为我使用过的 WCF HTTP 客户端清除 PooledBufferManager?
我有一个 WCF 客户端应用程序,它发出一个具有非常大响应 (1GB) 的服务调用。我发现进行此服务调用会使用大量内存(500MB),即使我的代码不再引用响应对象,这些内存似乎也永远不会被回收。
我使用内存分析器查看了大部分内存使用情况是由 PooledBufferManager 实例创建的字节数组。
我使用的代理/客户端是由 Visual Studio 自动生成的,所以它是一个派生自 System.ServiceModel.ClientBase<TChannel> 的类。
我正在使用具有以下配置的自定义绑定:
阅读周围的人谈论一些解决方案:
- 切换到流式响应模式而不是缓冲,但我相信这是用于 TCP WCF 连接,而不是像我这样的 HTTP。
- 将 maxBufferPoolSize 设置为零以禁用缓冲池。在 httpTransport 元素中设置它似乎对我没有任何影响。
- 在适当的 BufferManager/PooledBufferManager 上调用 Clear()。我无法从我拥有的 ClientBase 派生实例的上下文中找到要调用它的对象。我确实设法使用调试器找到了合适的 PooledBufferManager 实例,并深入挖掘了许多级别到私有 innerChannelFactory 字段,但这对于从代码中与之交互没有用处。
- 手动调用 GC.Collect() 似乎回收了剩余的 500MB 中的大约 50MB。
尽可能多地回收此一次性服务调用所使用的内存的最佳方法是什么?我即将在一个专用进程中进行服务调用,此时我可以杀死以回收内存。
wcf - WCF BufferManager ReturnBuffer 与 Clear
我在我的 WCF 服务中使用 BufferManager。我创建了自己的类来包装实现 IDisposable 的 BufferManager。现在我的 Dispose 方法如下所示:
我的问题:这是否与在经理已占用的所有缓冲区上调用 ReturnBuffer 完成相同的事情?
只是为了一些背景:我在以下方法中使用 BufferManager:
我这样做的原因是因为我不断收到 OutOfMemory 异常,这会破坏服务。
主机服务器有 3 GB 内存。该服务处于 InstanceContextMode.Single 模式,因此一次处理一个图像。图像以字节数组的形式接收 - 最大的可能是 100MB,但通常要小得多 - 转换,然后作为字节数组返回。大对象堆上有很多内容,并且图像大小变化很大。
我想知道问题是否是堆碎片。
随着文档的每一页被转换,它被附加到磁盘上的临时文件中。转换后,我将整个转换后的文件从磁盘读取到一个字节数组中并返回给客户端。
标准的 File.ReadAllBytes 方法在从文件中读取时会创建一个新的字节数组,由于我正在使用的图像大小,这不可避免地会出现在 LOH 上(我假设这就是发生的情况)。我创建了 ReadAllBufferedBytes 方法来做同样的事情,但缓冲字节数组并让 BufferManager 在释放缓冲区时返回它。
另一个问题是:我什至需要做这一切吗?
azure - Azure Storage BufferManager 有什么作用,我如何/何时实现它?
MSDN 上的cloudBlobClient.BufferManager文档描述了这个缓冲区管理器提高了大规模应用程序的性能。
我的理解是,这个缓冲区管理器减少了许多小事务的 GC 压力(就像在许多 Azure Table 实体调用中出现的那样),
然后我阅读了有关桌面使用的参考资料,桌面/移动使用配置文件似乎不太可能遇到 GC 碎片:
IBufferManager 接口仿照 System.ServiceModel.dll 中的 BufferManager 类进行设计,以允许桌面客户端轻松利用框架提供的现有实现。
问题
IBufferManager 的唯一目的是减轻 GC 的压力吗?
哪些工作负载(表、队列、Blob)将从该缓存中受益?
我应该在哪些(可测量的)条件下实现 IBufferManager?
BufferManager 线程安全吗?我可以根据需要分配一个运行时服务器端缓冲区池吗?
我应该/不应该如何实现这个bufferManager?(例如线程、IDisposable、静态方法中的预分配、Redis)
lru - 什么 LRU 变体页面替换策略处理顺序泛洪?
在顺序泛洪的情况下,LRU 命中率很差。
要了解什么是顺序泛洪,请查看此 CS186 课程:https ://www.youtube.com/watch?v=cESKTl12Ulg
并且教授介绍了MRU,它在顺序泛洪的情况下表现更好。但是 MRU 不考虑时间局部性。
有更好的 LRU 变体,例如 LRU-K、LRU 2Q。在顺序泛洪的情况下,它们的性能是否比 LRU 更好?在顺序泛洪的情况下,哪种 LRU 变体页面替换策略表现良好?