本文转载自微信公众号「码农读书」,作者码农读书。转载本文请联系码农读书公众号。
Microsoft.IO.RecyclableMemoryStream 是一个被设计为专门用于提高 Stream 操作的高性能类库,意思很明显,专用于取代 MemoryStream 而生,RecyclableMemoryStream 可以最大限度的避免 Stream 操作在 GC 上的 LOH (大对象堆)的分配和内存碎片,泄露等烦人的问题,这篇文章我们将会讨论 Microsoft.IO.RecyclableMemoryStream 及如何在 .NET Core 应用程序中提升性能。
RecyclableMemoryStream 的价值
RecyclableMemoryStream 大体上提供了如下四点价值。
RecyclableMemoryStream 的原理
RecyclableMemoryStream 在2代堆上存储了一个用于流的大型缓冲区,并能够确保这个缓冲区在进程的生命周期内一直存在,这就确保了GC不会频繁的出现全量回收,同时 RecyclableMemoryStreamManager 类维护了两类缓冲池。
值得注意的是,大型缓冲池的扩容又分为 线性增长 和 指数型增长,可以看出内存可被高效的反复使用并且对调用者还是无感知的,这就是为什么 RecyclableMemoryStream 比 MemoryStream 更好更高效的原因。
当调用 GetBuffer() 方法时,小缓冲区将会转换为一个大的连续缓冲区,如下代码所示:
- var buffer = recyclableMemoryStreamManager.GetStream().GetBuffer();
安装 RecyclableMemoryStream
你可以通过 Nuget 可视化界面安装 Microsoft.IO.RecyclableMemoryStream 或者通过 NuGet package manager console window 执行如下命令。
- Install-Package Microsoft.IO.RecyclableMemoryStream
使用 RecyclableMemoryStream
安装好之后,接下来我们通过 RecyclableMemoryStream 将数据写入到 MemoryStream 中,值得注意的是,RecyclableMemoryStreamManager.GetStream() 方法返回的是 MemoryStream 实例。
- class Program
- {
- private static readonly RecyclableMemoryStreamManager recyclableMemoryStreamManager = new RecyclableMemoryStreamManager();
- static void Main(string[] args)
- {
- string data = "This is a sample text message.";
- var buffer = Encoding.ASCII.GetBytes(data);
- using (var memoryStream = recyclableMemoryStreamManager.GetStream())
- {
- memoryStream.Write(buffer, 0, buffer.Length);
- }
- Console.ReadKey();
- }
- }
上面的代码还有一点要注意,我将 RecyclableMemoryStreamManager 静态化了,意味着它只需要定义一次就ok了,还有一点你可以对 MemoryStream 进行标记,方便后续持续跟踪,如下代码所示:
- using (var memoryStream = recyclableMemoryStreamManager.GetStream("High_Performance_Stream_Demo.Program.Main"))
- {
- memoryStream.Write(buffer, 0, buffer.Length);
- }
对 MemoryStream Pool 精细化配置
如果你想对 MemoryStream Pool 做更精细化的配置,可以在 RecyclableMemoryStreamManager 实例上进行配置,如下代码所示:
- int blockSize = 1024;
- int largeBufferMultiple = 1024 * 1024;
- int maximumBufferSize = 16 * largeBufferMultiple;
- int maximumFreeLargePoolBytes = maximumBufferSize * 4;
- int maximumFreeSmallPoolBytes = 250 * blockSize;
- var recyclableMemoryStreamManager = new RecyclableMemoryStreamManager(blockSize, largeBufferMultiple, maximumBufferSize);
- recyclableMemoryStreamManager.AggressiveBufferReturn = true;
- recyclableMemoryStreamManager.GenerateCallStacks = true;
- recyclableMemoryStreamManager.MaximumFreeLargePoolBytes = maximumFreeLargePoolBytes;
- recyclableMemoryStreamManager.MaximumFreeSmallPoolBytes = maximumFreeSmallPoolBytes;
RecyclableMemoryStream 最佳实践
内存碎片会影响到程序的性能,而且LOH独有的链式管理也非常容易产生内存碎片,下面是使用 RecyclableMemoryStream 应该遵循的一些经验法则。
Microsoft.IO.RecyclableMemoryStream 是 MemoryStream 的池化对象,它技巧性的减少了 GC 的负载并减少了 LOH 的大对象分配,自然就提高了应用程序的性能,不仅避免了内存碎片和内存泄漏还提供了用于跟踪性能的指标。
译文链接:https://www.infoworld.com/article/3597060/how-to-use-recyclablememorystream-in-net-core.html
排查思路 无法通过远程桌面连接裸金属服务器时,我们推荐您按照以下思路排查问题...
公司介绍 我们公司是全球法律服务整合平台,已有的4万多名律师遍布全国359个城市...
案例背景 高校健康打卡项目发起于北京大学软件与微电子学院,是该学院张齐勋老师...
客户简介 趣医网(quyiyuan.com)创立于2014年,为京颐集团重要成员企业之一,是...
客户简介 全民直播是一家涵盖游戏、娱乐、户外等多领域泛娱乐的直播平台。2015年...
3月24日,腾讯发布2020年Q4及全年财报,其中金融科技及企业服务第四季收入385亿...
注册了 域名 不备案可以吗?可以的。 注册域名 并不是一定要备案的,只有搭 建网...
API风格说明 当前ECS服务对外开放两类风格的API: ECS服务自定义规范的API(以下...
云虚拟主机 可以干什么?云 虚拟主机 可以是搭 建网站 的重要产品,可用来存放网...
??提到慕尼黑,大家第一个想到总是啤酒节,其实慕尼黑的文化同样闻名世界。慕尼...