什么是 ArrayPool
System.Buffers 命名空間下提供了一個可對 array 進行復用的高性能池化類 ArrayPool<T>本股,在常常使用 array 的場景下可以使用 ArrayPool<T> 來減小內(nèi)存占用,它是一個抽象類罪佳。使用重用模式玩郊,專為創(chuàng)建成本高的對象設(shè)計腻异。池是預初始化對象的集合夷野,可以跨線程保留和釋放這些對象征堪。 池可以定義分配規(guī)則管毙,例如限制、預定義大小或增長率米酬。
如何理解Pool
能夠想象一下你的業(yè)務(wù)場景中須要屢次實例化 array沛豌,這么作有什么后果呢? 很顯然每一次 new array 都會在托管堆上分配赃额,同時當 array 再也不使用時還須要 GC 去釋放加派,而 ArrayPool<T> 就是為了解決此事而生的,它在池中動態(tài)維護若干個 array 對象爬早,當你須要 new array 的時候只需從池中獲取便可哼丈。
未池化前:
[HttpGet("array/{size}")]
public byte[] GetArray(int size)
{
var random = new Random();
var array = new byte[size];
random.NextBytes(array);
return array;
}
池化后:
[ApiController]
[Route("api/[controller]")]
public class PoolController : Controller
{
private static ArrayPool<byte> _arrayPool = ArrayPool<byte>.Create();
public class PooledArray : IDisposable
{
public byte[] Array { get; private set; }
public PooledArray(int size)
{
Array = _arrayPool.Rent(size);
}
public void Dispose()
{
_arrayPool.Return(Array);
}
}
[HttpGet("pooledarray/{size}")]
public byte[] GetPooledArray(int size)
{
var pooledArray = new PooledArray(size);
var random = new Random();
random.NextBytes(pooledArray.Array);
HttpContext.Response.RegisterForDispose(pooledArray); //通過注冊釋放pooledArray對象
return pooledArray.Array;
}
}