本文共 6564 字,大约阅读时间需要 21 分钟。
本文是对微软官方文档的翻译解读。由于官方文档采用机器翻译生成,部分内容可能存在不准确或不完整的情况。如有任何疑问或发现错误,请随时指出。
.NET框架中的内存管理系统通过一系列强类型内存区域实现连续内存访问。主要组成包括:
System.Span<T>:用于访问连续内存区域,支持堆栈分配,适用于局部缓冲。System.ReadOnlySpan<T>:不可变版本的Span,适用于只读场景。System.Memory<T>:包装连续内存区域,支持托管堆存储,无需复制数据。System.ReadOnlyMemory<T>:不可变版本的Memory,适用于只读场景。System.Buffers.MemoryPool<T>:内存池管理强类型内存块,支持租用和释放。System.Buffers.IMemoryOwner<T>:内存块所有权管理接口。MemoryManager<T>:扩展内存管理,适用于高级场景。ArraySegment<T>:数组段表示法,支持特定起始位置和长度的内存访问。System.MemoryExtensions:内存扩展方法集,支持String、数组和数组段转换。这些类型的设计目标是避免不必要的内存复制和托管堆分配,通过引用更新和偏移实现高效内存操作。
在多线程和异步环境中,内存缓冲区的生命周期管理至关重要。主要包括以下核心概念:
以下示例展示了缓冲区的所有权、消费者和租约概念:
using System;using System.Buffers;class Program{ static void Main() { var buffer = CreateBuffer(); try { int value = Int32.Parse(Console.ReadLine()); WriteInt32ToBuffer(value, buffer); DisplayBufferToConsole(buffer); } finally { buffer.Destroy(); } } private static void WriteInt32ToBuffer(int value, Buffer buffer) { var strValue = value.ToString(); var span = buffer.Span; for (int ctr = 0; ctr < strValue.Length; ctr++) span[ctr] = strValue[ctr]; } private static void DisplayBufferToConsole(Buffer buffer) { Console.WriteLine($"Contents of the buffer: '{buffer}'"); }} .NET Core支持两种内存管理模型:
无需显式使用 IMemoryOwner
using System;class Example{ static void Main() { Memory memory = new char[64]; Console.Write("Enter a number: "); var value = Int32.Parse(Console.ReadLine()); WriteInt32ToBuffer(value, memory); DisplayBufferToConsole(memory); } private static void WriteInt32ToBuffer(int value, Memory buffer) { var strValue = value.ToString(); strValue.AsSpan().CopyTo(buffer.Slice(0, strValue.Length).Span); } private static void DisplayBufferToConsole(Memory buffer) { Console.WriteLine($"Contents of the buffer: '{buffer}'"); }} 在使用 Memory
以下示例展示了如何使用 IMemoryOwner
using System;using System.Buffers;class Example{ static void Main() { using (var owner = MemoryPool .Shared.Rent()) { Console.Write("Enter a number: "); try { var value = Int32.Parse(Console.ReadLine()); var memory = owner.Memory; WriteInt32ToBuffer(value, memory); DisplayBufferToConsole(memory.Slice(0, value.ToString().Length)); } catch (FormatException) { Console.WriteLine("You did not enter a valid number."); } catch (OverflowException) { Console.WriteLine($"You entered a number less than {Int32.MinValue:N0} or greater than {Int32.MaxValue:N0}."); } finally { owner.Dispose(); } } } private static void WriteInt32ToBuffer(int value, Memory buffer) { var strValue = value.ToString(); var span = buffer.Slice(0, strValue.Length).Span; strValue.AsSpan().CopyTo(span); } private static void DisplayBufferToConsole(Memory buffer) { Console.WriteLine($"Contents of the buffer: '{buffer}'"); }} 以下示例展示了如何使用隐式所有权:
using System;class Example{ static void Main() { Memory memory = new char[64]; Console.Write("Enter a number: "); var value = Int32.Parse(Console.ReadLine()); WriteInt32ToBuffer(value, memory); DisplayBufferToConsole(memory); } private static void WriteInt32ToBuffer(int value, Memory buffer) { var strValue = value.ToString(); strValue.AsSpan().CopyTo(buffer.Slice(0, strValue.Length).Span); } private static void DisplayBufferToConsole(Memory buffer) { Console.WriteLine($"Contents of the buffer: '{buffer}'"); }} 以下示例展示了如何在异步操作中使用 Memory
using System;using System.Buffers;using System.Runtime.InteropServices;class Example{ static async Task ManagedWrapperAsync(Memory data) { var tcs = new TaskCompletionSource (); var state = new MyCompletedCallbackState { Tcs = tcs }; var pState = (IntPtr)GCHandle.Alloc(state); var memoryHandle = data.Pin(); state.MemoryHandle = memoryHandle; try { int result = ExportedAsyncMethod((byte*)memoryHandle.Pointer, data.Length, pState, _callbackPtr); if (result != PENDING) { MyCompletedCallbackImplementation(pState, result); } return result; } catch { ((GCHandle)pState).Free(); memoryHandle.Dispose(); throw; } return tcs.Task; } private static void MyCompletedCallbackImplementation(IntPtr state, int result) { GCHandle handle = (GCHandle)state; var actualState = (MyCompletedCallbackState)handle.Target; handle.Free(); actualState.MemoryHandle.Dispose(); if (error) { actualState.Tcs.SetException(...); } else { actualState.Tcs.SetResult(result); } } private static IntPtr GetCompletionCallbackPointer() { OnCompletedCallback callback = MyCompletedCallbackImplementation; GCHandle.Alloc(callback); return Marshal.GetFunctionPointerForDelegate(callback); } private class MyCompletedCallbackState { public TaskCompletionSource Tcs; public MemoryHandle MemoryHandle; }} 通过遵循这些最佳实践,可以在内存管理和缓冲区使用中实现高效、安全且可靠的代码。
转载地址:http://bdozz.baihongyu.com/