.net core在新增的System.Buffers中引入了一大堆高效内存管理的类,如span和memory、内存池。本文今天这里介绍一个高效动态内存访问方案。

ReadOnlySequenceSegment<T>

在我们读取数据的过程,很多时候会出现如下场景:

  1. 不知道数据实际大小

  2. 一次性申请大量内存开销太大

此时我们往往会使用动态内存的方案,通过链表的方式串联起来,从而形成逻辑意义上的数据流。如下图所示:

ReadOnlySequenceSegment<T>就是这样一个表示数据流节点的内存模型,它是一个抽象类,包含如下三个元素:

  • Memory        指向所包含的内存

  • Next        指向下一个节点

  • RunningIndex        标志当前节点在整个流的位置

其中Memory和Next还比较容易理解,典型的链表结构。主要难理解的是RunningIndex,他表示该节点在数据流中的Memory起始索引。

一般的来讲,某节点的RunningIndex为其上一个节点的RunningIndex + Memory.Length。加上RunningIndex估计主要是为了快速索引的。

例如:对于如下3快内存 100byte, 200byte, 300byte组成的链表,其RunningIndex分别是0, 100, 200。

另外,在实际的使用过程中,往往是不停的释放链表头部的节点,并且在尾部添加新节点。 RunningIndex表示的索引一般是逻辑意义上的索引,在释放头节点时,一般不用更新其子节点以及后续节点的RunningIndex。

ReadOnlySequence<T>

ReadOnlySequenceSegment<T>虽然能解决我们的动态内存的申请和释放问题,但它往往并不好用,因为很容易出现一段连续的数据被分割在多个节点的情况,在这段不连续的数据里进行查询是非常不便的。

为了解决这个问题,.net core中推出了一个视图类ReadOnlySequence<T>

ReadOnlySequence<T>由两个属性标记:

  • Start: 起始SequenceSegment以及起始索引

  • End: 结尾SequenceSegment以及结尾索引

可以通过foreach遍历各节点的Memory

  var seq = new ReadOnlySequence<byte>();  foreach (ReadOnlyMemory<byte> memory in seq)  {  }

ReadOnlySequence的主要优势在于,它可以看成一段逻辑意义上的连续内存,常用的函数有:

  • Slice: 对视图数据切片

  • PositionOf: 查询元素的缩影

  • ToArray: 转换成数组

其中的ToArray涉及到大量的数据拷贝,需要谨慎使用。

另外.net core 3.0中还内置了一个SequenceReader,用起来是十分方便的:

如何使用

用过System.IO.Pipelines的朋友就知道,ReadOnlySequence在该库中是非常好用的。但如果我们想常见一个ReadOnlySequence,发现并不是那么容易,因为:

  1. ReadOnlySequence依赖于ReadOnlySequenceSegment

  2. ReadOnlySequenceSegment是抽象类,需要自己继承

也就是说我们需要自己实现ReadOnlySequenceSegment<T>,然后再将其封装到ReadOnlySequence中,目前.net core中并没有内置实现可能是因为在高效内存管理的方案中并没有什么通用的解决方案吧。

如果我们要自己实现ReadOnlySequence,一般需要如下几个步骤:

  1. 继承ReadOnlySequenceSegment类,实现自己的SequenceSegment

  2. 在申请内存过程中,创建SequenceSegment,并将其挂成链表

  3. 使用数据时,在该链表中创建ReadOnlySequence

  4. 当SequenceSegment节点的内存使用完成的时候,从链表中接触该节点,并释放内存。

简单来说就是如下几种操作:

  • 数据读取: 创建SequenceSegment

  • 数据使用: 在SequenceSegment链表上创建ReadOnlySequence

  • 使用完成: 释放SequenceSegment

如果要更进一步优化,在SequenceSegment中的内存申请和释放可以使用内存池。

原文地址:https://www.cnblogs.com/TianFang/p/10084049.html

.NET社区新闻,深度好文,欢迎访问公众号文章汇总 http://www.csharpkit.com

.net core中的高效动态内存管理方案相关推荐

  1. FreeRTOS 之五 动态内存管理(heap_1.c)详解

    写在前面   写这篇文章时,网上已经有了铺天盖地的文章来介绍 FreeRTOS 的动态内存.之所以还去写这篇博文,主要还是记录自己的学习过程.结合源代码一步一步分析一下FreeRTOS究竟是怎么实现的 ...

  2. 一个基于链表的内存管理方案

    在Open×××中,一种很不错的内存管理方案是基于链表的,该方案的实现使用了一个gc_arena结构体,该结构体的作用就是将所有的动态分配的内存块收集汇集起来,然后就可以在一个地方统一释放,c语言对动 ...

  3. C++学习笔记-DLL中动态内存管理

    动态内存管理 在dll中malloc的内存,必须在dll中free 注:这是由Windows自己的特点决定! 如果 a 编译成静态库,有下面两种解决方法: 1.b.dll 和 c.dll 使用同一个款 ...

  4. LwIP 之五 详解动态内存管理 内存堆(mem.c/h)

    写在前面   目前网上有很多介绍LwIP内存的文章,但是绝大多数都不够详细,甚至很多介绍都是错误的!无论是代码的说明还是给出的图例,都欠佳!下面就从源代码,到图例详细进行说明.   目前,网络上多数文 ...

  5. C++ 动态内存管理:c/c++的动态内存管理,new/delete,operator new/delete,placement-new, 内存泄漏

    c/c++的动态内存管理 new/delete opeartor new/delete placement-new 内存泄漏 c/c++的动态内存管理 在开始之前首先要了解c和c++的内存分布,我简单 ...

  6. 动态内存管理:malloc和free以及new和delete的联系与区别

    动态内存管理:malloc和free以及new和delete的联系与区别 文章目录 动态内存管理:malloc和free以及new和delete的联系与区别 一. C/C++中程序内存区域划分: 二. ...

  7. 内存区划分;内存分配;堆、栈概念分析;动态内存管理数据结构及程序样例;核心态与用户态...

    一. 在c中分为这几个存储区1.栈 - 由编译器自动分配释放 2.堆 - 一般由程序员分配释放,若程序员不释放,程序结束时可能由OS回收 3.全局区(静态区),全局变量和静态变量的存储是放在一块的,初 ...

  8. 【C进阶】动态内存管理

    ⭐博客主页:️CS semi主页 ⭐欢迎关注:点赞收藏+留言 ⭐系列专栏:C语言进阶 ⭐代码仓库:C Advanced 家人们更新不易,你们的点赞和关注对我而言十分重要,友友们麻烦多多点赞+关注,你们 ...

  9. 【带你吃透C++】C++动态内存管理

    C++动态内存管理 前言 1. C/C++内存分布 例题理解 2.C语言中动态内存管理方式( malloc/calloc/realloc和free) 3.C++中动态内存管理方式 new和delete ...

最新文章

  1. 拼音怎么写_老师:不会写的字用圈代替,看到孩子试卷,网友:人才
  2. PHP 获取IP地址 获取当前时间 写文件
  3. LiveVideoStack线上交流分享 (十七) —— AV1编码器优化与实用落地演进之路
  4. refreshtoken用mysql_微信access_token和refresh_token保存于redis
  5. Codeforces 884E E. Binary Matrix
  6. halcon区域腐蚀膨胀算子_Halcon 形态学膨胀腐蚀应用举例
  7. Visual C#中父窗口和子窗口之间实现控件互操作
  8. SQL Server中的尾日志备份和还原
  9. python 实现注册、登录功能
  10. mui下载 mui.js下载 mui.css下载
  11. 350网店模板一键安装模版与淘宝传统装修的对比
  12. ApiPost使用教程
  13. 油藏弹性存储量计算公式_低渗透油藏压裂井弹性产能和采收率计算方法
  14. tensorflow 如何计算向量余弦相似 cosine similarity
  15. how-I-hacked-Facebook-again-unauthenticated-RCE-on-MobileIron-MDM笔记
  16. vue-baidu-api地图标记点(自定义标记图标),设置标记点的优先级
  17. C 中的auto register static extern的使用
  18. linux+swap分区规则_linux关于swap分区的划分规则
  19. macOS Big Sur 系统启动U盘制作教程
  20. 圣诞老人的礼物_圣诞节设计资源:圣诞老人

热门文章

  1. [转载]C/C++框架和库
  2. Optaplanner规划引擎的工作原理及简单示例(1)
  3. linux下简单的备份的脚本 2 【转】
  4. 更改windows2003远程最大连接数
  5. 战神II导演 首席程序员访谈(转自www.npc6.com )
  6. CA周记 - 用 Visual Studio Code 做基于 .NET MAUI 跨平台移动应用开发
  7. 使用 NetCoreBeauty 优化 .NET CORE 独立部署目录结构
  8. C# 使用Awaiter
  9. 虎年云原生落地技术趋势
  10. WPF GridControl控件的用法举例