ArrayPool<T> 是 .NET 中的一个高性能数组池,用于减少内存分配和垃圾回收的开销。
基本用法
// 基本使用方式
public void BasicUsage()
{
// 从共享池获取数组
char[] array = ArrayPool<char>.Shared.Rent(100);
try
{
// 使用数组
// ... 业务逻辑 ...
}
finally
{
// 归还数组到池中
ArrayPool<char>.Shared.Return(array);
}
}
高级用法
// 创建自定义数组池
public class CustomArrayPoolExample
{
private readonly ArrayPool<byte> _customPool;
public CustomArrayPoolExample()
{
// 创建最大数组长度为1024,最多保留10个数组的池
_customPool = ArrayPool<byte>.Create(maxArrayLength: 1024, maxArraysPerBucket: 10);
}
public void UseCustomPool()
{
// 从自定义池租用数组
byte[] buffer = _customPool.Rent(256);
try
{
// 使用数组
// ... 业务逻辑 ...
}
finally
{
// 清除敏感数据
Array.Clear(buffer, 0, buffer.Length);
// 归还数组
_customPool.Return(buffer);
}
}
}
性能优化示例
public class HighPerformanceExample
{
private static readonly ArrayPool<char> _charPool = ArrayPool<char>.Shared;
public string ProcessLargeString(string input)
{
char[] buffer = _charPool.Rent(input.Length * 2);
try
{
// 处理字符串
int resultLength = ProcessBuffer(input, buffer);
return new string(buffer, 0, resultLength);
}
finally
{
_charPool.Return(buffer);
}
}
private int ProcessBuffer(string input, char[] buffer)
{
// 处理逻辑
return input.Length;
}
}
最佳实践
使用 using 语句
public string SafeArrayPoolUsage(int size)
{
using var owner = MemoryPool<char>.Shared.Rent(size);
var memory = owner.Memory;
// 使用 memory
return memory.ToString();
}
/**
需要直接数组操作,选择 ArrayPool
需要安全性保证,选择 MemoryPool
异步操作推荐 MemoryPool
高性能场景推荐 ArrayPool
*/
避免常见错误
// 错误示例 - 不要这样做
var array = ArrayPool<int>.Shared.Rent(100);
// 忘记返回数组 - 内存泄漏!
// 正确示例
var array = ArrayPool<int>.Shared.Rent(100);
try
{
// 使用数组
}
finally
{
ArrayPool<int>.Shared.Return(array);
}
使用场景
大数据处理场景
public class BigDataProcessor
{
private readonly ArrayPool<byte> _pool = ArrayPool<byte>.Shared;
public void ProcessLargeData(Stream stream)
{
byte[] buffer = _pool.Rent(81920); // 80KB 缓冲区
try
{
while (stream.Read(buffer, 0, buffer.Length) > 0)
{
// 处理数据
}
}
finally
{
_pool.Return(buffer);
}
}
}
图像处理
public class ImageProcessor
{
private readonly ArrayPool<byte> _pixelPool = ArrayPool<byte>.Shared;
public void ProcessImage(Bitmap bitmap)
{
byte[] pixels = _pixelPool.Rent(bitmap.Width * bitmap.Height * 4);
try
{
// 处理图像像素
}
finally
{
_pixelPool.Return(pixels);
}
}
}
网络通信
public class NetworkHandler
{
private readonly ArrayPool<byte> _networkPool = ArrayPool<byte>.Shared;
public async Task HandleNetworkData(NetworkStream stream)
{
byte[] buffer = _networkPool.Rent(4096);
try
{
await stream.ReadAsync(buffer, 0, buffer.Length);
// 处理网络数据
}
finally
{
_networkPool.Return(buffer);
}
}
}
字符串处理
public class StringProcessor
{
private readonly ArrayPool<char> _charPool = ArrayPool<char>.Shared;
public string ProcessLargeString(string input)
{
char[] buffer = _charPool.Rent(input.Length * 2);
try
{
// 字符串处理逻辑
return new string(buffer, 0, input.Length);
}
finally
{
_charPool.Return(buffer);
}
}
}
高频临时数组
public class HighFrequencyProcessor
{
private readonly ArrayPool<int> _intPool = ArrayPool<int>.Shared;
public void ProcessData()
{
int[] tempArray = _intPool.Rent(1000);
try
{
// 高频临时计算
}
finally
{
_intPool.Return(tempArray, clearArray: true); // 清除敏感数据
}
}
}
适合场景
频繁创建和销毁数组的场景
- 大型数组操作
- 需要临时缓冲区的操作
- 性能敏感的应用
不适合场景
- 长期持有数组的场景
- 数组大小不固定频繁变化
- 小型数组(小于16字节)
- 生命周期不确定的场景
性能优化建议
- 使用 using 语句确保返回
- 适当设置 clearArray 参数
- 选择合适的数组大小
- 避免过度池化
注意事项
- 必须及时返回数组
- 注意线程安全
- 不要修改已返回的数组
- 考虑内存占用
ArrayPool 是一个强大的性能优化工具,但需要在合适的场景下使用,并注意正确的使用方式