第2代回收,当大于85000字节时,我们看到了第一次的Full GC回收。
Method SizeInBytes Mean StdDev Gen 0/1/2 AllocatedRentAndReturn_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 AllocatedAllocate 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
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