在C#开发中,除了托管堆内存之外,很多时候需要和底层系统交互或者追求更高的内存操作性能,这时候就需要使用非托管内存也就是本机内存。NativeMemory是.NET中专门用于分配和释放本机内存的类,提供了多种灵活的分配方式,避免了传统Marshal类操作非托管内存的繁琐步骤。

NativeMemory常用分配方法
分配指定字节数的内存
最基础的方法是Alloc,它可以分配指定大小的本机内存,返回值是指向内存起始地址的void*指针。需要注意分配的内存不会初始化,里面是随机的垃圾数据。
using System;
using System.Runtime.InteropServices;
class Program
{
static void Main()
{
// 分配100字节的本机内存
int size = 100;
void* ptr = NativeMemory.Alloc((nuint)size);
try
{
// 使用内存的逻辑,比如写入数据
// 注意需要手动处理指针操作,避免越界
}
finally
{
// 必须手动释放内存,否则会造成内存泄漏
NativeMemory.Free(ptr);
}
}
}
分配对齐内存
如果需要分配指定对齐要求的本机内存,可以使用AlignedAlloc方法,它支持传入对齐参数,适合需要内存对齐的场景,比如SIMD指令操作或者和某些底层库交互的需求。
using System;
using System.Runtime.InteropServices;
class Program
{
static void Main()
{
// 分配1024字节内存,内存地址按32字节对齐
nuint size = 1024;
nuint alignment = 32;
void* alignedPtr = NativeMemory.AlignedAlloc(size, alignment);
try
{
// 验证对齐是否符合要求
nuint address = (nuint)alignedPtr;
Console.WriteLine($"内存地址: {address}, 是否32字节对齐: {address % alignment == 0}");
}
finally
{
// 对齐内存必须使用对应的AlignedFree释放
NativeMemory.AlignedFree(alignedPtr);
}
}
}
分配数组形式的本机内存
如果需要分配连续的多元素本机内存,类似数组的结构,可以使用AllocArray方法,它会计算元素数量乘以单个元素大小的总内存,并返回对应类型的指针。
using System;
using System.Runtime.InteropServices;
class Program
{
static void Main()
{
// 分配10个int类型的本机内存数组
int elementCount = 10;
int* intArrayPtr = (int*)NativeMemory.AllocArray<int>((nuint)elementCount);
try
{
// 给数组元素赋值
for (int i = 0; i < elementCount; i++)
{
intArrayPtr[i] = i * 10;
}
// 读取验证数据
for (int i = 0; i < elementCount; i++)
{
Console.WriteLine($"第{i}个元素: {intArrayPtr[i]}");
}
}
finally
{
NativeMemory.Free(intArrayPtr);
}
}
}
使用NativeMemory的注意事项
- 本机内存不受.NET垃圾回收管理,分配之后必须手动调用对应的释放方法,否则会造成内存泄漏,建议配合try-finally块使用确保释放逻辑执行。
- 不同的分配方法必须对应对应的释放方法,
Alloc和AllocArray分配的内存用Free释放,AlignedAlloc分配的内存必须用AlignedFree释放,混用会导致未定义行为。 - 操作本机内存指针的时候要注意越界访问,本机内存没有托管内存的边界检查,越界写入可能会破坏其他内存数据,导致程序崩溃或者数据错误。
- 如果需要将本机内存的数据转换为托管类型,需要使用
Marshal类的相关方法,比如PtrToStringUTF8、Copy等,避免直接转换导致类型错误。
和传统非托管内存操作方式的对比
在NativeMemory出现之前,C#操作非托管内存通常使用Marshal.AllocHGlobal或者Marshal.AllocCoTaskMem,和这些方法相比,NativeMemory的优势更明显:
| 对比项 | NativeMemory | Marshal.AllocHGlobal |
|---|---|---|
| 内存对齐支持 | 原生支持对齐分配 | 不直接支持,需要手动计算偏移实现 |
| 数组分配便捷性 | 提供AllocArray直接分配数组 | 需要手动计算总大小再分配 |
| 内存释放对应性 | 分配和释放方法分类清晰 | 统一用Marshal.FreeHGlobal释放,容易混淆 |
使用本机内存的核心原则是按需分配、及时释放,同时要严格控制指针操作的边界,避免内存安全问题。NativeMemory提供了更贴合本机内存操作习惯的API,能简化很多非托管内存操作的流程。
NativeMemoryC#非托管内存本机内存分配修改时间:2026-06-30 18:33:44