多层次缓冲区池 BufferPoolManager
适用场景:
适用于文件上传、图像处理、网络数据传输等大量数据处理时,
内存分配频繁,大对象堆碎片化严重;
GC压力大,频繁触发垃圾回收,导致响应时间不稳定,影响性能,用户体验差;
Demo
var totalProcessed = 0;
var fi = new FileInfo(filePath);
using (var stream = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read, 4096, useAsync: true))
{
var buffer = _poolManager.GetBuffer((int)fi.Length);
try
{
int bytesRead;
while ((bytesRead = await stream.ReadAsync(buffer, 0, buffer.Length, token)) > 0)
{
// TODO
totalProcessed += bytesRead;
}
}
finally
{
_poolManager.ReturnBuffer(buffer);
}
}
BufferPoolManager
using Microsoft.Extensions.ObjectPool;
using System;
using System.Collections.Generic;
using System.IO;
using System.Threading;
using System.Threading.Tasks;
/// <summary>
/// 多层次缓冲区池管理器
/// </summary>
/// <remarks>根据数据大小智能分配不同规格的缓冲区</remarks>
public class BufferPoolManager
{
/// <summary>
/// 8KB
/// </summary>
public const int SMALLBUFFERSIZE = 8 * 1024;
/// <summary>
/// 64KB
/// </summary>
public const int MEDIUMBUFFERSIZE = 64 * 1024;
/// <summary>
/// 1MB
/// </summary>
public const int LARGEBUFFERSIZE = 1024 * 1024;
/// <summary>
/// 8MB
/// </summary>
public const int SUPERBUFFERSIZE = 8 * 1024 * 1024;
/// <summary>
/// 小文件 8KB
/// </summary>
private readonly ObjectPool<byte[]> _smallBufferPool;
/// <summary>
/// 中等文件 64KB
/// </summary>
private readonly ObjectPool<byte[]> _mediumBufferPool;
/// <summary>
/// 大文件 1MB
/// </summary>
private readonly ObjectPool<byte[]> _largeBufferPool;
/// <summary>
/// 超大文件 8MB
/// </summary>
private readonly ObjectPool<byte[]> _superBufferPool;
/// <summary>
/// 小文件监控池 使用计数器
/// </summary>
private int _smallBufferCount;
/// <summary>
/// 中等文件监控池 使用计数器
/// </summary>
private int _mediumBufferCount;
/// <summary>
/// 大文件监控池 使用计数器
/// </summary>
private int _largeBufferCount;
/// <summary>
/// 超大文件监控池 使用计数器
/// </summary>
private int _superBufferCount;
public BufferPoolManager()
{
_smallBufferPool = new DefaultObjectPool<byte[]>(new BufferPoolPolicy(SMALLBUFFERSIZE));
_mediumBufferPool = new DefaultObjectPool<byte[]>(new BufferPoolPolicy(MEDIUMBUFFERSIZE));
_largeBufferPool = new DefaultObjectPool<byte[]>(new BufferPoolPolicy(LARGEBUFFERSIZE));
_superBufferPool = new DefaultObjectPool<byte[]>(new BufferPoolPolicy(SUPERBUFFERSIZE));
}
/// <summary>
/// 获取缓冲区:根据需要的大小选择合适的池
/// </summary>
/// <param name="size">B</param>
/// <returns></returns>
public byte[] GetBuffer(int size)
{
if (size <= SMALLBUFFERSIZE)
{
Interlocked.Increment(ref _smallBufferCount);
return _smallBufferPool.Get();
}
if (size <= MEDIUMBUFFERSIZE)
{
Interlocked.Increment(ref _mediumBufferCount);
return _mediumBufferPool.Get();
}
if (size <= LARGEBUFFERSIZE)
{
Interlocked.Increment(ref _largeBufferCount);
return _largeBufferPool.Get();
}
Interlocked.Increment(ref _superBufferCount);
return _superBufferPool.Get();
}
/// <summary>
/// 归还缓冲区到对应的池中
/// </summary>
/// <param name="buffer"></param>
public void ReturnBuffer(byte[] buffer)
{
if (buffer.Length <= SMALLBUFFERSIZE)
{
Interlocked.Decrement(ref _smallBufferCount);
_smallBufferPool.Return(buffer);
}
else if (buffer.Length <= MEDIUMBUFFERSIZE)
{
Interlocked.Decrement(ref _mediumBufferCount);
_mediumBufferPool.Return(buffer);
}
else if (buffer.Length <= LARGEBUFFERSIZE)
{
Interlocked.Decrement(ref _largeBufferCount);
_largeBufferPool.Return(buffer);
}
else
{
Interlocked.Decrement(ref _superBufferCount);
_superBufferPool.Return(buffer);
}
}
public string GetDetailInfo()
{
return $" 小:{_smallBufferCount} 中:{_mediumBufferCount} 大:{_largeBufferCount} 特大:{_superBufferCount}";
}
}
/// <summary>
/// 缓冲区池策略:定义如何创建和重用缓冲区
/// </summary>
internal class BufferPoolPolicy : IPooledObjectPolicy<byte[]>
{
private readonly int _bufferSize;
public BufferPoolPolicy(int bufferSize)
{
_bufferSize = bufferSize;
}
/// <summary>
/// 创建新的缓冲区
/// </summary>
/// <returns></returns>
public byte[] Create()
{
return new byte[_bufferSize];
}
/// <summary>
/// 决定对象是否可以重用
/// </summary>
/// <param name="obj"></param>
/// <returns></returns>
public bool Return(byte[] obj)
{
if (obj == null || obj.Length != _bufferSize)
{
return false;
}
// 这里可以选择清空缓冲区,但会影响性能
// 在大多数场景下,不清空也是安全的
// Array.Clear(obj, 0, obj.Length);
return true;
}
}

浙公网安备 33010602011771号