使用ArrayPool池化大型数组(翻译) (3)

第2代回收,当大于85000字节时,我们看到了第一次的Full GC回收。

Method SizeInBytes Mean StdDev Gen 0/1/2 Allocated
RentAndReturn_Shared   100   44.219 ns   0.0314 ns   -   0 B    
RentAndReturn_Shared   1000   43.739 ns   0.0337 ns   -   0 B    
RentAndReturn_Shared   10000   44.223 ns   0.0333 ns   -   0 B    
RentAndReturn_Shared   100000   46.649 ns   0.0346 ns   -   0 B    
RentAndReturn_Shared   1000000   42.423 ns   0.0623 ns   -   0 B    

此刻,你应该注意到了,ArrayPool

被分配的缓存

如果当我们在给定的池中租赁的缓存超过了最大长度限制(2^20,ArrayPool.Shared)会发生什么呢?

Method SizeInBytes Mean Gen 0 Gen 1 Gen 2 Allocated
Allocate   10000000   557,963.968 ns   211.5625   211.5625   211.5625   10000024 B  
RentAndReturn_Shared   10000000   651,147.998 ns   207.1484   207.1484   207.1484   10000024 B  
RentAndReturn_Aware   10000000   47.033 ns   -   -   -   0 B  

当超过了最大长度限制,每一次运行时都会重新分配一段新的缓存区。并且当你把它还到池里的时候,都会被忽略而不是再放入池中。

别担心,ArrayPool

使用ArrayPool池化大型数组(翻译)

使用ArrayPool池化大型数组(翻译)

为了避免这种问题,你可以使用ArrayPool

MemoryStream的池化

有时,为了避免LOH的分配一个数组可能不是很够,有个第三方API的,
感谢Victor Baybekov我发现了Microsoft.IO.RecyclableMemoryStream库,这个库提供了MemoryStream对象的池化,这个是Bing的工程师为了解决LOH问题所涉及的。想要知道更多细节可以查看Ben Watson写的这篇博客。

总结

LOH = 第2代 = Full GC = 糟糕的性能

ArrayPool 被设计为更好的性能

如果你能控制生命周期可以使用池化

默认使用ArrayPool

池化的时候分配的内存不要超过最大数组长度限制

池越少,LOH就会越小,效率越好

原文链接:https://www.cnblogs.com/briswhite/p/11349429.html

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zyzwgg.html