.NET高性能内存管理

.NET高性能内存管理

你是不是还不了解span、Memeory、ArrayPool这些用法,随着.net的不断升级,像这些提高性能的用法也层出不穷,本文重点介绍一些能够提升.net性能的用法

开篇之前,先说下提高性能的宗旨,无非就是尽量减少堆上重新分配与数据复制,让内存得以重用或在栈上分配,从而降低 GC 压力、提升访问速度

Span、ReadOnlySpan

它是栈上的结构(ref struct),所以不会触发GC,可以提供数组、字符串等的零拷贝切片,生命周期仅仅局限于当前的栈,也就是当前方法结束,就会清除,不可以跨方法或者异步操作传递。
ReadOnlySpan<T> 是 ref struct,只能用于:局部变量、方法参数/返回值,或 ref struct 的实例字段。

整体比较好用,不过我觉得比较鸡肋的一点是只能在同步方法中使用,不能再异步方法中传递,因为await本质会把方法状态机移到堆上,不过又推出了Memory解决了这个问题,见下文。

csharp 复制代码
{
    string csv = "1,2,3,4,5";
    ReadOnlySpan<char> span = csv.AsSpan();
    ReadOnlySpan<char> firstTwo = span.Slice(0, 3);
    firstTwo.ToString().Display(); // 输出 "1,2"此时没有有新的字符串分配
    csv.Substring(0,3).Display(); // 输出 "1,2",此时有新的字符串分配
}

Span<T>仅创建视图,不分配新对象,相比 Substring 或数组切片性能高且无 GC 影响。

堆上切片Memory 、 ReadOnlyMemory

特点和用法类似于Span,不同点时可以分配到堆上

csharp 复制代码
async Task<int> ReadStreamAsync(Stream stream)
{
    Memory<byte> buffer = new byte[1024];
    int bytesRead = await stream.ReadAsync(buffer);
    return bytesRead;
}

上面返回的是Memory类型,传统的方式是返回byte\[\],但是byte\[\] 可能导致异步复制,Memory 可直接传递,减少内存分配

在实际开发中,Span其实可以和Memory根据需求进行转换,比如Memory转换成span
Span<T> span = buffer.Span

同样,也可以把span转换为Memory
Memory<T> m = MemoryMarshal.AsMemory(span);

相关推荐
邹肖桥3 小时前
使用S7.net动态库对西门子Plc S7-1200进行通讯操作
.net
chingho7 小时前
GitHub上这10个C#项目,不仅实用,还怪好玩的
c#·github·.net·开源项目
学以智用8 小时前
Visual Studio 模板详解
.net
波力海苔夹心脆6752 天前
C# 机器视觉实战:单相机引导机械手精准贴合,从拍照、偏差计算(平移+旋转)到坐标补偿全解
开发语言·经验分享·数码相机·c#·视觉检测·.net
慧都小妮子2 天前
Stimulsoft 2026.4 发布:Markdown 组件、桑基图与 .NET 11 支持
.net·数据可视化·stimulsoft·版本更新·报表控件·桑基图·.net 11
波力海苔夹心脆6753 天前
C# 视觉检测实战:PLC 按钮触发 VisionPro 检测,OK 亮灯 / NG 灭灯(西门子 PLC,含界面显示与图片存档)
开发语言·经验分享·c#·自动化·视觉检测·.net
hez20103 天前
一行代码在 .NET 项目里启用 Satori GC
c#·.net·.net core·gc·clr
QUDONG_biubiubiu3 天前
.NET Runtime 6.0/7.0/8.0/9.0下载修复教程,软件打不开这样解决
.net·net runtime下载·net运行库修复·net runtime安装
宝桥南山3 天前
.NET 11 - 尝试创建一下AGUIServer和AGUIClient(基于新版.NET SDK for AG-UI)
microsoft·ai·微软·c#·aigc·.net
波力海苔夹心脆6753 天前
C# LINQ 入门到上手:一篇讲透查询语法、常用操作符与延迟执行(含示例与速查表
经验分享·c#·.net·solr·linq