如何实现我自己的字节数组创建和处理

时间:2009-09-20 21:41:43

标签: c# garbage-collection

背景

在通过分析器运行我的应用程序时,看起来热点都涉及分配大量临时新byte []数组。

在CLR Profiler下的一次运行中,在一个千兆字节的垃圾中产生了一些短的(在探查器外面花费了3-5秒的CPU时间),其中大部分是byte []分配,这触发了超过500个集合。

在某些情况下,应用程序似乎花费了超过其执行收集的CPU时间的10%。

显然,重写是有序的。

所以,我正在考虑用一个可以在以后重用缓冲区的池类替换新的byte []分配。

像这样......

{
 byte[] temp = Pool.AllocateBuffer(1024);
 ...
 }

问题:

当不再需要temp时,如何强制应用程序调用例程Pool.deAllocate(temp)中的代码。

在上面的代码片段中,temp是Pool分配的byte []缓冲区,但是当它超出范围时会被删除。不是真正的问题,但不会被池重用。

我知道我可以替换“return 0;”使用“Pool.deAllocate(temp);返回0”,但我试图强制恢复发生。

这甚至是远程可能吗?

1 个答案:

答案 0 :(得分:4)

您可以实现一个Buffer类来实现IDisposable,并在缓存时将缓冲区返回到池中。然后,您可以访问基础字节数组,只要每个人都能很好地使用 ,您就可以利用重用。

但请注意:

  • 你的缓冲区将很快在第2代结束,这可能不是理想的其他原因
  • 如果恶意代码段保留对字节数组的引用,它们可能会监视其他代码使用的数据
  • 您需要记住在合适的时间处理缓冲区。

我实际上在MiscUtil中有一些代码来执行此操作 - 请参阅CachingBufferManagerCachedBuffer等。我不能说我已经使用了很多,请注意......从我记忆中来看,我让它变得比我真正需要的更复杂......

编辑:回复评论......

  • 你不能强制应用程序代码释放缓冲区,没有。 C#中没有自动释放机制 - using语句是我们最接近的。
  • 您可以在缓冲区类中实现对byte[]的隐式转换,以允许您调用具有字节数组参数的方法。就个人而言,我并不喜欢隐式转换,但它当然可以选择。