当前位置: 首页 > 科技观察

如何在C#中使用ArrayPool、MemoryPool

时间:2023-03-19 17:46:39 科技观察

本文转载请联系码农阅读公众号。资源的可重用性是提高应用程序性能的一个非常重要的手段。比如本文要分享的ArrayPool和MemoryPool,可以有效降低内存占用和GC压力,从而提升应用性能。什么是ArrayPoolSystem.Buffers命名空间提供了一个高性能的池化类ArrayPool,可以复用数组。在经常使用数组的场景下,可以使用ArrayPool来减少内存占用。它是一个抽象类,如下代码所示:publicabstractclassArrayPool{}你可以想象在你的业务场景中需要多次实例化数组。释放需要GC,ArrayPool就是为了解决这个问题而诞生的。它在池中动态维护几个数组对象。当你需要一个新的数组时,你只需要从池中获取它。使用ArrayPool可以通过以下三种方式使用ArrayPool。通过ArrayPool.Shared属性获取一个ArrayPool实例。通过ArrayPool.Create()创建一个ArrayPool实例。通过继承ArrayPool生成自定义子类。以下代码显示如何从ArrayPool中获取大小>=10的数组。varshared=ArrayPool.Shared;varrentedArray=shared.Rent(10);上面代码需要注意的是,虽然只租了10个size,但是底层会返回一个2的倍数的size,也就是图中的2*8=16,当rentedArray不再需要的时候,记得归还到ArrayPool,如以下代码所示。shared.Return(rentedArray);下面是完整的代码,仅供参考。staticvoidMain(string[]args){varshared=ArrayPool.Shared;varrentedArray=shared.Rent(10);for(inti=0;i<10;i++){rentedArray[i]=i+1;}for(intj=0;j<10;j++){Console.WriteLine(rentedArray[j]);}shared.Return(rentedArray);Console.ReadKey();}创建一个自定义的ArrayPool你也可以重写ArrayPool来实现一个自定义池化对象,如下代码所示:}}使用MemoryPoolSystem.Memory命名空间提供内存池对象MemoryPool。在此之前,每次都需要创建一个新的内存块,这也增加了GC的负担。有了MemoryPool之后,你需要的内存Blocks直接从池中取出。staticvoidMain(string[]args){varmemoryPool=MemoryPool.Shared;varrentedArray=memoryPool.Rent(10);for(inti=0;i<10;i++){rentedArray.Memory.Span[i]=i+1;}for(intj=0;j<10;j++){Console.WriteLine(rentedArray.Memory.Span[j]);}Console.ReadKey();}ArrayPoolvsMemoryPool从上面的演示可以看出,ArrayPool是以数组的形式出租的,而MemoryPool是以内存块的形式出租的,所以在复用数组提高性能的场景下可以优先选择ArrayPool。如果你的代码是内存块的形式,比如Memory多用途,优先使用MemoryPool。翻译链接:https://www.infoworld.com/article/3596289/how-to-use-arraypool-and-memorypool-in-c.html