厦门网站建设价格,海南网站网络推广,网站点击量与排名,中国科技成就有哪些近两年.net core在新增的System.Buffers中引入了一大堆高效内存管理的类#xff0c;如span和memory、内存池。本文今天这里介绍一个高效动态内存访问方案。ReadOnlySequenceSegmentT在我们读取数据的过程#xff0c;很多时候会出现如下场景#xff1a;不知道数据实际大小一… .net core在新增的System.Buffers中引入了一大堆高效内存管理的类如span和memory、内存池。本文今天这里介绍一个高效动态内存访问方案。 ReadOnlySequenceSegmentT在我们读取数据的过程很多时候会出现如下场景不知道数据实际大小一次性申请大量内存开销太大此时我们往往会使用动态内存的方案通过链表的方式串联起来从而形成逻辑意义上的数据流。如下图所示ReadOnlySequenceSegmentT就是这样一个表示数据流节点的内存模型它是一个抽象类包含如下三个元素Memory 指向所包含的内存Next 指向下一个节点RunningIndex 标志当前节点在整个流的位置其中Memory和Next还比较容易理解典型的链表结构。主要难理解的是RunningIndex他表示该节点在数据流中的Memory起始索引。一般的来讲某节点的RunningIndex为其上一个节点的RunningIndex Memory.Length。加上RunningIndex估计主要是为了快速索引的。例如对于如下3快内存 100byte 200byte 300byte组成的链表其RunningIndex分别是0 100 200。另外在实际的使用过程中往往是不停的释放链表头部的节点并且在尾部添加新节点。 RunningIndex表示的索引一般是逻辑意义上的索引在释放头节点时一般不用更新其子节点以及后续节点的RunningIndex。 ReadOnlySequenceTReadOnlySequenceSegmentT虽然能解决我们的动态内存的申请和释放问题但它往往并不好用因为很容易出现一段连续的数据被分割在多个节点的情况在这段不连续的数据里进行查询是非常不便的。为了解决这个问题.net core中推出了一个视图类ReadOnlySequenceTReadOnlySequenceT由两个属性标记Start 起始SequenceSegment以及起始索引End 结尾SequenceSegment以及结尾索引可以通过foreach遍历各节点的Memory var seq new ReadOnlySequencebyte(); foreach (ReadOnlyMemorybyte memory in seq) { }ReadOnlySequence的主要优势在于它可以看成一段逻辑意义上的连续内存常用的函数有Slice 对视图数据切片PositionOf 查询元素的缩影ToArray 转换成数组其中的ToArray涉及到大量的数据拷贝需要谨慎使用。另外.net core 3.0中还内置了一个SequenceReader用起来是十分方便的如何使用用过System.IO.Pipelines的朋友就知道ReadOnlySequence在该库中是非常好用的。但如果我们想常见一个ReadOnlySequence发现并不是那么容易因为ReadOnlySequence依赖于ReadOnlySequenceSegmentReadOnlySequenceSegment是抽象类需要自己继承也就是说我们需要自己实现ReadOnlySequenceSegmentT然后再将其封装到ReadOnlySequence中目前.net core中并没有内置实现可能是因为在高效内存管理的方案中并没有什么通用的解决方案吧。如果我们要自己实现ReadOnlySequence一般需要如下几个步骤继承ReadOnlySequenceSegment类实现自己的SequenceSegment在申请内存过程中创建SequenceSegment并将其挂成链表使用数据时在该链表中创建ReadOnlySequence当SequenceSegment节点的内存使用完成的时候从链表中接触该节点并释放内存。简单来说就是如下几种操作数据读取 创建SequenceSegment数据使用 在SequenceSegment链表上创建ReadOnlySequence使用完成 释放SequenceSegment如果要更进一步优化在SequenceSegment中的内存申请和释放可以使用内存池。原文地址:https://www.cnblogs.com/TianFang/p/10084049.html.NET社区新闻深度好文欢迎访问公众号文章汇总 http://www.csharpkit.com