.net core中高效的动态内存管理方案

 更新时间:2022年07月02日 11:12:01   作者:天方  
这篇文章介绍了.net core中高效的动态内存管理方案,文中通过示例代码介绍的非常详细。对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下

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

ReadOnlySequenceSegment<T>

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

  • 不知道数据实际大小

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

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

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,用起来是十分方便的: 

private static ReadOnlySpan<byte> CRLF => new byte[] { (byte)'\r', (byte)'\n' };
 
public static void ReadLines(ReadOnlySequence<byte> sequence)
{
    SequenceReader<byte> reader = new SequenceReader<byte>(sequence);
 
    while (!reader.End)
    {
        if (!reader.TryReadToAny(out ReadOnlySpan<byte> line, CRLF, advancePastDelimiter: false))
        {
            // Couldn't find another delimiter
            // ...
        }
 
        if (!reader.IsNext(CRLF, advancePast: true))
        {
            // Not a good CR/LF pair
            // ...
        }
 
        // line is valid, process
        ProcessLine(line);
    }
}

如何使用

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

  • ReadOnlySequence依赖于ReadOnlySequenceSegment

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

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

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

  • 继承ReadOnlySequenceSegment类,实现自己的SequenceSegment

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

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

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

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

  • 数据读取: 创建SequenceSegment

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

  • 使用完成: 释放SequenceSegment

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

到此这篇关于.net core动态内存管理方案的文章就介绍到这了。希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

相关文章

  • asp.net服务器上几种常见异常的解决方案.

    asp.net服务器上几种常见异常的解决方案.

    由于以前就业时算是公司里对服务器上各种硬件和配置原理较为了解. 一直负责公司服务器日常管理.也算是半路出家. 当然日常工作中前前后后也遇到不少大大小小的问题(硬件/服务器日常配置 数据中心合并方案等等). 有1些常见的异常. 总结一些基本快速的处理方法.
    2009-11-11
  • Microsoft Visual Studio 2017 for Mac Preview安装使用案例分享

    Microsoft Visual Studio 2017 for Mac Preview安装使用案例分享

    这篇文章主要为大家分享了Microsoft Visual Studio 2017 for Mac Preview安装使用案例,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2016-11-11
  • 提交页面的定位--scrollIntoView的用法

    提交页面的定位--scrollIntoView的用法

    提交页面的定位--scrollIntoView的用法...
    2007-03-03
  • .NET垃圾回收GC诊断工具dotnet-gcmon使用

    .NET垃圾回收GC诊断工具dotnet-gcmon使用

    这篇文章主要介绍了.NET垃圾回收GC诊断工具dotnet-gcmon使用方法,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2021-11-11
  • 解析如何利用一个ASP.NET Core应用来发布静态文件

    解析如何利用一个ASP.NET Core应用来发布静态文件

    本文主要通过一些简单的实例来体验一下如何在一个ASP.NET Core应用中发布静态文件。针对不同格式的静态文件请求的处理,ASP.NET Core为我们提供了三个中间件,它们将是本系列文章论述的重点。有需要的朋友可以看下
    2016-12-12
  • Global.asax取绝对路径的方法

    Global.asax取绝对路径的方法

    通过string absolutelyPath可设置对路径,具体代码如下,感兴趣的朋友可以参考下哈,希望对你有所帮助
    2013-04-04
  • SqlDataReader指定转换无效的解决方法

    SqlDataReader指定转换无效的解决方法

    这篇文章主要为大家详细介绍了SqlDataReader指定转换无效的解决方法,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-06-06
  • ASP.NET实现学生管理系统

    ASP.NET实现学生管理系统

    这篇文章主要为大家详细介绍了ASP.NET实现学生管理系统,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2015-11-11
  • ASP.NET Core MVC自定义Tag Helpers用法介绍

    ASP.NET Core MVC自定义Tag Helpers用法介绍

    这篇文章介绍了ASP.NET Core MVC自定义Tag Helpers的用法,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-02-02
  • IIS服务器发布ASP.NET项目

    IIS服务器发布ASP.NET项目

    如何在云服务器上部署一个项目,需要做哪些配置准备,本文就来介绍一下IIS服务器发布ASP.NET项目,具有一定的参考价值,感兴趣的可以了解一下
    2024-03-03

最新评论