.Net性能调优-MemoryPool
简单用法
//获取MemoryPool实例,实际返回了一个ArrayMemoryPool<T>
MemoryPool<char> Pool = MemoryPool<char>.Shared;
//加上using
using IMemoryOwner<char> owner = Pool.Rent(1024 * 900);
Memory<char> memory = owner.Memory;
for (int i = 0; i < 1024 * 900; i++)
{
memory.Span[i] = 'x';
}
//从100的下标开始截取10个字符
var sliceArr = memory.Span.Slice(100, 10).ToArray();
ArrayMemoryPool<T>
通过MemoryPool<int>.Shared我们可以获取到一个MemoryPool<T>的示例,该实例的类型为ArrayMemoryPool<T>
ArrayMemoryPool<T>实际上只有一个函数可用,就是Rent(),还有一个Dispose()函数但是里面没有任何代码
Rent()限制了最大租借长度:2147483647u=(1024^3*2-1)=(2G-1bytes),并返回一个IMemoryOwner<T>对象
ArrayMemoryPoolBuffer<T>
ArrayMemoryPool<T>的Rent()实际返回了一个ArrayMemoryPoolBuffer<T>,该类继承了IMemoryOwner<T>
它提供一个Memroy属性来获取一个Memory<T>对象,我们可以借助Memroy<T>来操控我们租用的数组了
ArrayMemoryPool<T>的内部实际还是调用的ArrayPool<T>.Shared 来租用数组
实现代码如下:
public Memory<T> Memory
{
get
{
T[] array = _array;
if (array == null)
{
System.ThrowHelper.ThrowObjectDisposedException_ArrayMemoryPoolBuffer();
}
return new Memory<T>(array);
}
}
public ArrayMemoryPoolBuffer(int size)
{
_array = ArrayPool<T>.Shared.Rent(size);
}
public void Dispose()
{
T[] array = _array;
if (array != null)
{
_array = null;
ArrayPool<T>.Shared.Return(array);
}
}
Memory<T>
Memory<T>的构造函数接收一个array<T>,存在私有变量_object中。Memory中对数组的操作最终又依赖于Span<T>
public readonly struct Memory<T> : IEquatable<Memory<T>>
{
private readonly object _object;
private readonly int _index;
private readonly int _length;
public static Memory<T> Empty => default(Memory<T>);
public int Length => _length;
public bool IsEmpty => _length == 0;
public unsafe Span<T> Span=>{ _object...}
public T[] ToArray()
{
return Span.ToArray();
}
}
Slice(start,length)
public Memory<T> Slice(int start)
{
return new Memory<T>(_object, _index + start, _length - start);
}
Memory的Slice函数可以对数组进行截取,该函数仍然返回一个Memory<T>对象,新的对象记录了原始的_object和要切割的index、length,所以该函数不会造成额外的内存消耗
Pin()
该函数的作用是获取数组内存的管理权,不让垃圾回收器回收,自己管理内存,但他怎么自己管理的,暂时木有研究。。。有兴趣的小伙伴可以自行研究。
但是因为我们的数组是从ArrayPool<T>租借的,由ArrayMemoryPool<T>的Dispose函数回收的,所以本文对于Memory的使用方式中并不会用到该函数
所以综上所述,简单的理解就是Memory<T>主要是用来管理Span<T>的
那么Span又是啥呢?为什么Memrory<T>不直接提供操作数组的方式,而是要返回一个Span<T>呢?
啊哈哈,这个就问倒我了
简单地概括其原因就是通过Span<T>来操作数组切割分片赋值等,更快,更节约内存,数据流转无复制。而Span本身过于底层,使用方面有很多的局限性。所以最终改用Memory<T>来控制Span<T>的生命周期,而只给用户提供Span的操作数组的相关函数。
至于它怎么底层了,局限性在哪些方面,想深入研究的话网上有很多相关的优秀文章值得阅读一下。对于Span的学习我现在是适可而止,后面把内存需要学习的相关知识学的差不多的时候再回来研究它吧,欠的债早晚是要还的啊...
使用场景
啊这...,对于MemoryPool,确实没有想到使用场景。因为之前的文章曾经介绍过ArrayPool。而MemoryPool的数组又是依赖ArrayPool创建的,反而相比于ArrayPool他又多了创建IMemoryOwner的消耗。这里推荐一篇文章对二者进行了对比:https://endjin.com/blog/2020/09/arraypool-vs-memorypool-minimizing-allocations-ais-dotnet。
其实我们更需要的是Memory<T>和Span<T>,在System.Memory命名空间下的MemoryExtensions为我们的Array[]提供了扩展方法AsMemory\<T\>(this T[]? array) AsSpan\<T\>(this T[]? array)等等几十种扩展,足够满足你的需要
所以如果不是非得要用MemoryPool的场景还是推荐直接使用ArrayPool吧,当然如果你有必须使用MemoryPool的场景还请在下面留言告诉我一下是什么场景,互相学习一下,嘿嘿
.Net性能调优-MemoryPool的更多相关文章
- [Spark性能调优] 源码补充 : Spark 2.1.X 中 Unified 和 Static MemoryManager
本课主题 Static MemoryManager 的源码鉴赏 Unified MemoryManager 的源码鉴赏 引言 从源码的角度了解 Spark 内存管理是怎么设计的,从而知道应该配置那个参 ...
- web前端性能调优
最近2个月一直在做手机端和电视端开发,开发的过程遇到过各种坑.弄到快元旦了,终于把上线了.2个月干下来满满的的辛苦,没有那么忙了自己准备把前端的性能调优总结以下,以方便以后自己再次使用到的时候得于得心 ...
- [网站性能2]Asp.net平台下网站性能调优的实战方案
文章来源:http://www.cnblogs.com/dingjie08/archive/2009/11/10/1599929.html 前言 最近帮朋友运营的平台进行了性能调优,效果还不错, ...
- Asp.net平台下网站性能调优的实战方案(转)
转载地址:http://www.cnblogs.com/chenkai/archive/2009/11/07/1597795.html 前言 最近帮朋友运营的平台进行了性能调优,效果还不错,所以写出来 ...
- 第0/24周 SQL Server 性能调优培训引言
大家好,这是我在博客园写的第一篇博文,之所以要开这个博客,是我对MS SQL技术学习的一个兴趣记录. 作为计算机专业毕业的人,自己对技术的掌握总是觉得很肤浅,博而不专,到现在我才发现自己的兴趣所在,于 ...
- sqlserver性能调优第一步
相信不少的朋友,无论是做开发.架构的,还是DBA等,都经常听说“调优”这个词.说起“调优”,可能会让很多技术人员心头激情澎湃,也可能会让很多人感觉苦恼,不知道如何入手.当然,也有很多人对此不屑一顾,因 ...
- JavaScript:内存泄露、性能调优
1.在进行JS内存泄露检查之前,先要了解JS的内存管理: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Memory_Manageme ...
- hadoop 性能调优与运维
hadoop 性能调优与运维 . 硬件选择 . 操作系统调优与jvm调优 . hadoop运维 硬件选择 1) hadoop运行环境 2) 原则一: 主节点可靠性要好于从节点 原则二:多路多核,高频 ...
- JVM性能调优监控工具jps、jstack、jmap、jhat、jstat、hprof使用详解
摘要: JDK本身提供了很多方便的JVM性能调优监控工具,除了集成式的VisualVM和jConsole外,还有jps.jstack.jmap.jhat.jstat.hprof等小巧的工具,本博客希望 ...
随机推荐
- Python中strip()、lstrip()、rstrip()函数的用法
Python中使用函数strip().lstrip().rstrip()来剔除字符串前后的特定字符 函数语法为:str.strip(chars) 返回值是一个新的字符串,不更改源字符串 其中,参数ch ...
- 获取元素在页面中位置 getBoundingClientRect()
DOM 原生方法getBoundingClientRect()获取元素相对视口位置 DOMRect 对象包含了一组用于描述边框的只读属性--left.top.right和bottom,单位为像素.除了 ...
- Python开发篇——基于React-Dropzone开发上传组件
这次我要讲述的是在React-Flask框架上开发上传组件的技巧.我目前主要以React开发前端,在这个过程中认识到了许多有趣的前端UI框架--React-Bootstrap.Ant Design.M ...
- 实战爬取Plati官网游戏实时最低价格-Python
需要修改url中的id_r="这个",这个id需要从Battlefield V (plati.ru)中获取,其实也是这个链接中的#s24235. 配合了e-mail推送,其实这个e ...
- 关于协议栈XDATA,内存溢出的小结
[第二部分的内容仅供参考,自己不是十分确定] ************************************************************** ************** ...
- CNVD-2021-14536 锐捷 RG-UAC 统一上网行为管理审计系统信息泄露漏洞
漏洞简介 锐捷 RG-UAC 统一上网行为管理审计系统存在信息泄露,攻击者通过网页源代码可间接获取管理用户账号密码,登录管理后台. 漏洞复现 fofa搜索以下关键字 title="RG-UA ...
- DVWA-sql注入(盲注)
DVWA简介 DVWA(Damn Vulnerable Web Application)是一个用来进行安全脆弱性鉴定的PHP/MySQL Web应用,旨在为安全专业人员测试自己的专业技能和工具提供合法 ...
- MySQL数据类型 储存引擎
存储引擎 日常生活中文件格式有很多种,并且针对不同的文件格式会有对应不同存储方式和处理机制(txt,pdf,word,mp4...) 针对不同的数据应该对应着不同的处理机制来存储 存储引擎就是不同的处 ...
- 【HMC Core 6.0全球上线】图形计算服务新插件,助力高画质3D手游创新
HMS Core 6.0已于7月15日全球上线,本次新版本向广大开发者开放了众多全新能力与技术.其中华为图形计算服务(CG Kit)开放了体积雾插件和流体插件,为3D手游画面的提升提供了坚实的技术基础 ...
- c# – RichTextBox用表情符号/图像替换字符串
在RichtTextBox中,我想用表情符号图像自动替换表情符号字符串(例如:D).我到目前为止工作,除了当我在现有的单词/字符串之间写出表情符号字符串时,图像会在行尾插入. 例如:你好(在这里插入: ...