2012-08-13 97 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#中根本沒有辦法重新調整數組的大小(無論是否固定)。你只能創建一個所需大小的新數組。

如果您創建一個新陣列,則無法將其固定到舊陣列被固定的位置。

相關問題