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

Noa*_*oah 5 c# garbage-collection

背景:

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

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

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

显然,重写是有序的.

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

像这样......

{
 byte[] temp = Pool.AllocateBuffer(1024);
 ...
 }
Run Code Online (Sandbox Code Playgroud)

题:

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

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

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

这甚至可以远程实现吗?

Jon*_*eet 4

您可以实现一个Buffer类,该类实现IDisposable缓冲区并将其在释放后返回到池中。然后,您可以授予对底层字节数组的访问权限,只要每个人都玩得很好,您就可以利用重用。

但请注意:

  • 您的缓冲区很快就会进入第 2 代,由于其他原因,这可能并不理想
  • 如果恶意代码保留对字节数组的引用,他们就可以监视其他代码使用的数据
  • 您需要记住在正确的时间处理缓冲区。

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

编辑:回应评论...

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