如何在 C# 中使用 ArrayPool 和 MemoryPool
对资源的可复用是提升应用程序性能的一个非常重要的手段,比如本篇要分享的 ArrayPool 和 MemoryPool,它们就有效的减少了内存使用和对GC的压力,从而提升应用程序性能。
什么是 ArrayPool
System.Buffers 命名空间下提供了一个可对 array 进行复用的高性能池化类 ArrayPool<T>
,在经常使用 array 的场景下可使用 ArrayPool<T>
来减少内存占用,它是一个抽象类,如下代码所示:
public abstract class ArrayPool<T>
{
}
可以想象一下你的业务场景中需要多次实例化 array,这么做有什么后果呢? 很显然每一次 new array 都会在托管堆上分配,同时当 array 不再使用时还需要 GC 去释放,而 ArrayPool<T>
就是为了解决此事而生的,它在池中动态维护若干个 array 对象,当你需要 new array
的时候只需从池中获取即可。
使用 ArrayPool<T>
可以通过下面三种方式来使用 ArrayPool<T>
。
通过
ArrayPool<T>.Shared
属性来获取ArrayPool<T>
实例。通过
ArrayPool<T>.Create()
来生成ArrayPool<T>
实例。通过继承
ArrayPool<T>
来生成一个自定义子类。
下面的代码展示了如何从 ArrayPool 中获取一个 size >= 10
的 array 数组。
var shared = ArrayPool<int>.Shared;
var rentedArray = shared.Rent(10);
上面的代码一定要注意,虽然只租用了 10 个 size,但底层会返回 2的倍数
的size , 也就是图中的 2* 8 = 16。
当什么时候不需要 rentedArray 了,记得再将它归还到 ArrayPool 中,如下代码所示。
shared.Return(rentedArray);
下面是仅供参考的完整代码。
static void Main(string[] args)
{
var shared = ArrayPool<int>.Shared;
var rentedArray = shared.Rent(10);
for (int i = 0; i < 10; i++)
{
rentedArray[i] = i + 1;
}
for (int j = 0; j < 10; j++)
{
Console.WriteLine(rentedArray[j]);
}
shared.Return(rentedArray);
Console.ReadKey();
}
创建自定义的 ArrayPool
你也可以通过重写 ArrayPool 来实现自定义的池化对象,如下代码所示:
public class CustomArrayPool<T> : ArrayPool<T>
{
public override T[] Rent(int minimumLength)
{
throw new NotImplementedException();
}
public override void Return(T[] array, bool clearArray = false)
{
throw new NotImplementedException();
}
}
使用 MemoryPool<T>
System.Memory
命名空间下提供了一个内存池对象 MemoryPool<T>
,在这之前你需要每次都 new 一个内存块出来,同时也增加了 GC 的负担,有了 MemoryPool<T>
之后,你需要的内存块直接从池中拿就可以了。
static void Main(string[] args)
{
var memoryPool = MemoryPool<int>.Shared;
var rentedArray = memoryPool.Rent(10);
for (int i = 0; i < 10; i++)
{
rentedArray.Memory.Span[i] = i + 1;
}
for (int j = 0; j < 10; j++)
{
Console.WriteLine(rentedArray.Memory.Span[j]);
}
Console.ReadKey();
}
ArrayPool<T>
vs MemoryPool<T>
从上面的演示可以看出, ArrayPool<T>
是以 array
的形式向外租借,而 MemoryPool<T>
则是以 内存块
的方式向外租借,所以在重复使用 array 的场景下可以优选 ArrayPool<T>
来提高性能,如果你的代码是以 Memory<T>
这种内存块的形式多次使用则优先使用 MemoryPool<T>
。
更多精彩,欢迎订阅
译文链接:https://www.infoworld.com/article/3596289/how-to-use-arraypool-and-memorypool-in-c.html
如何在 C# 中使用 ArrayPool 和 MemoryPool的更多相关文章
- 我是如何在SQLServer中处理每天四亿三千万记录的
首先声明,我只是个程序员,不是专业的DBA,以下这篇文章是从一个问题的解决过程去写的,而不是一开始就给大家一个正确的结果,如果文中有不对的地方,请各位数据库大牛给予指正,以便我能够更好的处理此次业务. ...
- 如何在SpringBoot中使用JSP ?但强烈不推荐,果断改Themeleaf吧
做WEB项目,一定都用过JSP这个大牌.Spring MVC里面也可以很方便的将JSP与一个View关联起来,使用还是非常方便的.当你从一个传统的Spring MVC项目转入一个Spring Boot ...
- 如何在latex 中插入EPS格式图片
如何在latex 中插入EPS格式图片 第一步:生成.eps格式的图片 1.利用visio画图,另存为pdf格式的图片 利用Adobe Acrobat裁边,使图片大小合适 另存为.eps格式,如下图所 ...
- 如何正确的使用json?如何在.Net中使用json?
什么是json json是一种轻量级的数据交换格式,由N组键值对组成的字符串,完全独立于语言的文本格式. 为什么要使用json 在很久很久以前,调用第三方API时,我们通常是采用xml进行数据交互,但 ...
- [原创]如何在Parcelable中使用泛型
[原创]如何在Parcelable中使用泛型 实体类在实现Parcelable接口时,除了要实现它的几个方法之外,还另外要定义一个静态常量CREATOR,如下例所示: public static cl ...
- 如何在springMVC 中对REST服务使用mockmvc 做测试
如何在springMVC 中对REST服务使用mockmvc 做测试 博客分类: java 基础 springMVCmockMVC单元测试 spring 集成测试中对mock 的集成实在是太棒了!但 ...
- 如何在tomcat中如何部署java EE项目
如何在tomcat中如何部署java EE项目 1.直接把项目复制到Tomcat安装目录的webapps目录中,这是最简单的一种Tomcat项目部署的方法,也是初学者最常用的方法.2.在tomcat安 ...
- 【转】我是如何在SQLServer中处理每天四亿三千万记录的
原文转自:http://blog.jobbole.com/80395/ 首先声明,我只是个程序员,不是专业的DBA,以下这篇文章是从一个问题的解决过程去写的,而不是一开始就给大家一个正确的结果,如果文 ...
- 如何在JAVA中实现一个固定最大size的hashMap
如何在JAVA中实现一个固定最大size的hashMap 利用LinkedHashMap的removeEldestEntry方法,重载此方法使得这个map可以增长到最大size,之后每插入一条新的记录 ...
随机推荐
- Linux虚拟机封装成模板
对安装在VMware上的CentOS7.X进行封装,是为了后续的实验环境需要,可以批量去生成Linux系统.通过虚拟机模版来创建一台CentOS系统,跟原来机器一样,去掉了唯一性,而通过克隆出来的虚拟 ...
- 牛客网多校第5场 I vcd 【树状数组+离散化处理】【非原创】
题目:戳这里 学习博客:戳这里 作者:阿狸是狐狸啦 n个点,一个点集S是好的,当且仅当对于他的每个子集T,存在一个右边无限延长的矩形,使的这个矩形包含了T,但是和S-T没有交集. 求有多少个这种集合. ...
- Pycharm缺少环境变量+无法获取libcudnn.so.6
在终端输入: echo LD_LIBRARY_PATH, 并将其内容 添加至Pycharm的 run -> Edit configuration -> Environment variab ...
- 24 Days Of JavaScript mas
24 Days Of JavaScript mas Level up your JavaScript skills with a daily coding challenge from Decembe ...
- PWA & TWA
PWA & TWA https://www.bilibili.com/video/av68082979/ Service Worker workbox.js https://developer ...
- 可视化埋点 & XPath
可视化埋点 & XPath https://www.w3.org/TR/xpath-full-text-30/ 数据的准确性 采集时机 数据发送策略 full XPath demo XML & ...
- c++中运行lua
video 下载lua源码将src下面除了 lua.c和luac.c 的文件全部添加到项目中 #include <iostream> #include "lua.hpp" ...
- 详解稳定币圣杯USDN
稳定币飞速发展,USDN 一骑绝尘,但因合规问题饱受质疑.合规稳定币作为后来者,奋起直追,亦光耀夺目.而更符合区块链精神的稳定币(抵押其他资产生成稳定币),长期以来只有 Maker 的 DAI 能够在 ...
- HBase ——Shell操作
HBase --Shell操作 Q:你觉得HBase是什么? A:一种结构化的分布式数据存储系统,它基于列来存储数据. 基于HBase,可以实现以廉价PC机器集群存储海量数据的分布式数据库的解决方案. ...
- Vue学习笔记-Vue.js-2.X 学习(六)===>脚手架Vue-CLI(项目说明-Babel)
五 Vue学习-vue-cli脚手架学习(创建只选一个选项:Babel) 1. 项目目录说明 node_modules : 包管理文件夹 public : 静态资源 src : 源代码 gitign ...