2012-08-13 62 views
1

我正在开发一个具有垃圾回收功能的基本POC虚拟机。我使用的语言是C#,我使用固定的字节数组作为VM的内存。是否有可能动态增加内存的大小,而不移动.net GC?如何动态增加C#中固定数组的大小?

我使用的代码是非常简单的

byte[] _memory = new byte[2048]; 
var _gcHandle = GCHandle.Alloc(_memory, GCHandleType.Pinned); 
var _memHandler = _gcHandle.AddrOfPinnedObject(); 

如果我要重新大小在事后的代码_memory,我会怎么做,如果不拔除呢?我应该使用其他技术吗?

回答

1

不,如果你仔细想一想,就不可能做到可靠。

想象的存储器块被设定,如:

[some_string] [_存储器] [boxed_int32] [some_URI]

然后就不可能重新大小_memory而不移动它。

您希望得到的最好的电话是在可能的情况下重新调整大小的调用,而不是其他方式(或者失败并强制您通过复制重新调整大小,或者在必要时复制副本并让您知道哪种方法奏效)。

因此,它是不可能的,但是如何捕捉可能作为优化的情况呢?如果同时收集了[some_URI],该怎么办?令人遗憾的是(尽管对于大多数代码(包括应用程序的其他部分)真的很高兴),但对于这种相对罕见的情况,这不会起到优化的作用,因为已经对整个内存管理进行了优化,如果有差距,GC会把东西移到那个位置,以减少碎片。因为你固定阵列使得它在移动物体方面效率较低,所以增加了它的可能性(因为你可能已经迫使它在阵列之前没有一点空间)。

如果您的阵列位于LOH中,那么它之后的空间更有可能不被使用,但不太可能会被释放。因此,即使这种重新malloc有时可能在理论上工作,但它在任何给定时间工作的几率太小,不值得实施。

3

如果我想在之后的代码中重新调整_memory的大小,我将如何做到这一点,而不是取消固定它?

没有可靠的方法来做到这一点,并没有任何托管API来完成它。问题是,一旦内存被固定,它就无法移动。调整数组的大小很可能要求分配发生在不同的位置(因为在当前位置可能没有足够大的连续内存块)。

因此,您需要取消固定内存,重新分配/调整大小,然后创建新的固定数组。确保持有内存的任何本地代码(这将成为首先插入的原因)被更新为不使用先前的内存位置。

3

在C#中根本没有办法重新调整数组的大小(无论是否固定)。你只能创建一个所需大小的新数组。

如果您创建一个新阵列,则无法将其固定到旧阵列被固定的位置。

相关问题