C# | 使用Memory<T>高效地读写内存数据

简介: Memory<T>是什么?它是一种可变大小、可读写的内存块,可以安全地暴露给用户代码进行操作。为什么要使用Memory<T>?使用它有许多好处。最主要的是善用它可以提高代码的性能。因为Memory<T>是可变的,所以我们可以直接在内存中操作数据,而不需要进行额外的拷贝操作。使用Memory<T>还可以减少垃圾回收的压力,因为我们不需要创建新的对象来存储数据。Memory<T>还可以与Span<T>和ReadOnlySpan<T>类型一起使用,这些类型可以方便地对数据进行访问和操作。

image.png

C# | 使用Memory高效地读写内存数据

@[toc]

前言

Memory\是C# 7.2版本中引入的一种新类型,可以更加高效地读写内存数据。本文将介绍它的用途以及如何使用它来优化代码。

PS:由于微软的文档实在是太简约,故写此篇。

在这里插入图片描述


Memory介绍

Memory\是什么?

它是一种可变大小、可读写的内存块,可以安全地暴露给用户代码进行操作。

为什么要使用Memory\?

  1. 使用它有许多好处。最主要的是善用它可以提高代码的性能。因为Memory\是可变的,所以我们可以直接在内存中操作数据,而不需要进行额外的拷贝操作。
  2. 使用Memory\还可以减少垃圾回收的压力,因为我们不需要创建新的对象来存储数据。
  3. Memory\还可以与Span\和ReadOnlySpan\类型一起使用,这些类型可以方便地对数据进行访问和操作。

示例

一起来看几个Memory\的常见用法示例代码。

  1. 创建一个空内存块
Memory<int> emptyMemory = Memory<int>.Empty;
  1. 将内存块转换为数组
byte[] byteArray = new byte[10];
Memory<byte> memory = byteArray;
byte[] array = memory.Span.ToArray();
  1. 使用Slice方法来获取数据的子片段
int[] intArray = {
   
    1, 2, 3, 4, 5 };
Memory<int> memory = intArray;
Memory<int> slice = memory.Slice(2, 2);
  1. 使用MarshalTo方法将数据复制到指定的数组
int[] sourceArray = {
   
    1, 2, 3, 4, 5 };
Memory<int> sourceMemory = sourceArray;
int[] destinationArray = new int[5];
Memory<int> destinationMemory = destinationArray;
sourceMemory.MarshalTo(destinationMemory);
  1. 使用Pin方法获得指针
int[] intArray = {
   
    1, 2, 3, 4, 5 };
Memory<int> memory = intArray;
using (MemoryHandle handle = memory.Pin())
{
   
   
    IntPtr pointer = handle.Pointer;
    // 在指针上执行操作
}

这个例子使用Pin方法将内存块固定在内存,然后使用MemoryHandle对象获取指向内存块的指针,这样可以用指针操作数据。

  1. 使用CreateFromPinnedArray方法将固定的数组转换为内存块
int[] intArray = {
   
    1, 2, 3, 4, 5 };
GCHandle handle = GCHandle.Alloc(intArray, GCHandleType.Pinned);
Memory<int> memory = Memory<int>.CreateFromPinnedArray(intArray, handle.AddrOfPinnedObject(), intArray.Length);
  1. 使用Marshal方法将数据序列化为指定类型的结构体
struct MyStruct
{
   
   
    public int A;
    public int B;
}

Memory<byte> memory = new byte[] {
   
    1, 2, 3, 4, 5, 6, 7, 8 };
MyStruct myStruct = memory.Span.Marshal<MyStruct>();

结束语

使用Memory\可以更加高效的进行内存读写、提高性能、减少GC压力。希望这篇文章可以帮助你了解它的用途。如果您觉得本文对您有所帮助,请不要吝啬您的点赞和评论,提供宝贵的反馈和建议,让更多的读者受益。

相关文章
|
5天前
|
存储 Java C#
C# 中的值类型与引用类型:内存大小解析
C# 中的值类型与引用类型:内存大小解析
13 2
|
16天前
|
存储 分布式计算 监控
Java一分钟之-Hazelcast:内存数据网格
【6月更文挑战第17天】**Hazelcast是开源的内存数据网格(IMDG),加速分布式环境中的数据访问,提供内存存储、分布式计算、线性扩展及高可用性。常见挑战包括内存管理、网络分区和数据分布不均。通过配置内存限制、优化网络和分区策略可避免问题。示例展示如何创建Hazelcast实例并使用分布式Map。使用Hazelcast提升性能和扩展性,关键在于理解和调优。**
30 1
|
9天前
|
存储 C语言
数据在内存中的储存
数据在内存中的储存
12 3
|
9天前
|
存储 Java C++
Java虚拟机(JVM)管理内存划分为多个区域:程序计数器记录线程执行位置;虚拟机栈存储线程私有数据
Java虚拟机(JVM)管理内存划分为多个区域:程序计数器记录线程执行位置;虚拟机栈存储线程私有数据,如局部变量和操作数;本地方法栈支持native方法;堆存放所有线程的对象实例,由垃圾回收管理;方法区(在Java 8后变为元空间)存储类信息和常量;运行时常量池是方法区一部分,保存符号引用和常量;直接内存非JVM规范定义,手动管理,通过Buffer类使用。Java 8后,永久代被元空间取代,G1成为默认GC。
22 2
|
12天前
|
存储
数据在内存中的存储(2)
数据在内存中的存储(2)
25 5
|
12天前
|
存储 小程序 编译器
数据在内存中的存储(1)
数据在内存中的存储(1)
27 5
|
12天前
|
存储 编译器 C语言
数据在内存中的存储
数据在内存中的存储
17 2
|
11天前
|
存储
数据在内存中的存储(了解数据在内存中的存储规则,看这一篇就够了!)
数据在内存中的存储(了解数据在内存中的存储规则,看这一篇就够了!)
|
2天前
|
存储
|
11天前
|
存储 C语言
C语言----数据在内存中的存储(2)
C语言----数据在内存中的存储
16 0