简体   繁体   中英

What is ArrayPool in .NetCore - C#

I was reading the official ASP.NET Core Performance Best Practices documentation on Microsoft Website.

In order to increase performance, they recommend to use ArrayPool to store large array.

But, what is ArrayPool and how does that work? Looking on internet and official documentation didn't help me to understand how it works and in which scenario I should use it.

Let's get rid of the 20 array allocations and use an array pool instead. The Rent method of the ArrayPool class returns an array. With the argument, the array size is passed to the Rent method, and this method returns an array with at least this number of elements. The static Shared property of ArrayPool returns an ArrayPool instance that is shared. Instead of using the shared pool, you can also create a separate pool for a specific requirement instead. After usage, the array is returned to the pool with the Return method, and the memory can be re-used. Optional, you can clear the memory content before returning it to the pool.

private static void LocalUseOfSharedPool(int i)
{
    int[] arr = ArrayPool<int>.Shared.Rent(ARRAYSIZE);
    ShowAddress($"simple array {i}", arr);
    FillTheArray(arr);
    UseTheArray(arr);
    ArrayPool<int>.Shared.Return(arr);
}

Running the application, because the array is always returned to the pool before a new array is requested, the pool can always return the same memory:

 0x11E00012AF0 0x11E00012AF0 0x11E00012AF0 0x11E00012AF0 0x11E00012AF0 0x11E00012AF0 0x11E00012AF0 0x11E00012AF0 0x11E00012AF0 0x11E00012AF0 0x11E00012AF0 0x11E00012AF0 0x11E00012AF0 0x11E00012AF0 0x11E00012AF0 0x11E00012AF0 0x11E00012AF0 0x11E00012AF0 0x11E00012AF0 0x11E00012AF0

With this, garbage collection does not need to run. The memory used by the ArrayPool is reused.

For more information, Please go through https://csharp.christiannagel.com/2017/05/31/arraypool/

Adding to the existing answer:

Using ArrayPool over allocating with new puts the responsibility of freeing the memory on you. Thus your application might leak memory if not handled correctly.

In simple use cases where you create a buffer and release it in the same method, it makes sense to put it into a finally clause:

private static void LocalUseOfSharedPool(int i)
{
    int[] arr = ArrayPool<int>.Shared.Rent(ARRAYSIZE);
    try
    {
        ShowAddress($"simple array {i}", arr);
        FillTheArray(arr);
        UseTheArray(arr);
    }
    finally
    {
        ArrayPool<int>.Shared.Return(arr);
    }
}

In more complex cases you must make sure to not leak the memory in other ways.

Also note, that your buffer now has a lifetime. If you pass your array to another object B , you need to make sure, that object B is not using the array after your call to ArrayPool<>.Return .

Since using ArrayPool is a performance issue, measure the gains of using it, especially if you want to change an existing system.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM