什么是.NetCore中的ArrayPool-C#

时间:2019-11-15 09:08:08

标签: c# .net-core

我正在阅读Microsoft网站上的官方ASP.NET Core Performance Best Practices文档。

为了提高性能,他们建议使用ArrayPool存储大型数组。

但是,什么是ArrayPool?它如何工作?查阅互联网和官方文档并没有帮助我了解它的工作原理以及在哪种情况下应该使用它。

2 个答案:

答案 0 :(得分:1)

让我们摆脱20个数组分配,而改用数组池。 ArrayPool类的Rent方法返回一个数组。使用该参数,数组大小将传递给Rent方法,并且此方法返回至少包含此数量元素的数组。 ArrayPool的static Shared属性返回一个共享的ArrayPool实例。除了使用共享池,您还可以为特定要求创建一个单独的池。使用后,该数组将通过Return方法返回到池中,并且可以重复使用内存。可选,您可以先清除内存内容,然后再将其返回到池中。

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);
}

运行应用程序,因为总是在请求新数组之前将数组返回到池中,所以池始终可以返回相同的内存:

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

有了这个,垃圾收集就不需要运行了。 ArrayPool使用的内存被重用。

有关更多信息,请通过https://csharp.christiannagel.com/2017/05/31/arraypool/

答案 1 :(得分:1)

添加到现有答案中:

ArrayPoolnew一起使用会给您释放内存的责任。因此,如果处理不当,您的应用程序可能会泄漏内存。

在简单的用例中,您创建缓冲区并以相同的方法释放它,将它放入finally子句是有意义的:

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);
    }
}

在更复杂的情况下,您必须确保不要以其他方式泄漏内存。

还要注意,您的缓冲区现在具有生存期。如果将数组传递给另一个对象B,则需要确保在调用B之后,该对象ArrayPool<>.Return没有使用该数组。

由于使用ArrayPool会带来性能问题,因此请评估使用它的收益,尤其是在要更改现有系统的情况下。