1

ガベージコレクション機能を備えた基本的なPOCVMを開発しています。私が使用している言語はC#で、VMのメモリとしてピン留めされたバイト配列を使用しています。.net GCでメモリを移動せずに、メモリのサイズを動的に増やすことは可能ですか?

私が使用しているコードは非常に単純です

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

後でコード内の_memoryのサイズを変更したい場合、固定を解除せずにそれを行うにはどうすればよいですか?別のテクニックを使用する必要がありますか?

4

3 に答える 3

3

後でコード内の_memoryのサイズを変更したい場合、固定を解除せずにそれを行うにはどうすればよいですか?

これを行うための信頼できる方法はなく、それを実現するためのマネージAPIもありません。問題は、メモリが固定されると、移動できないことです。アレイのサイズを変更するには、別の場所で割り当てを行う必要があります(現在の場所に十分な大きさのメモリの連続したチャンクがない可能性があるため)。

そのため、メモリの固定を解除し、再割り当て/サイズ変更してから、新しい固定配列を作成する必要があります。メモリを保持しているネイティブコード(最初にピン留めする理由)が、以前のメモリ位置を使用しないように更新されていることを確認してください。

于 2012-08-13T15:36:49.970 に答える
3

C#では、配列のサイズを変更する方法はまったくありません(固定されているかどうかは関係ありません)。必要なサイズの新しいアレイのみを作成できます。

新しいアレイを作成する場合、古いアレイが固定されていた場所に固定する方法はありません。

于 2012-08-13T15:38:16.207 に答える
1

いいえ。考えてみれば、確実に行うことは不可能です。

メモリのチャンクが次のように設定されていると想像してください。

[some_string] [_ memory] ​​[boxed_int32] [some_URI]

_memoryそうすると、動かさずにサイズを変更することは不可能になります。

期待できる最善の方法は、可能であればサイズを変更し、それ以外の場合はサイズを変更しない呼び出しでした(失敗してコピーでサイズ変更を強制するか、必要に応じてコピーを実行して、どちらのアプローチが機能したかを知らせます) 。

したがって、それが可能である可能性は低いですが、最適化として可能である場合をキャッチするのはどうでしょうか。その間に[some_URI]が収集された場合はどうなりますか?

悲しいことに(アプリの残りの部分を含むコードの大部分では本当に幸いですが)、GCがものを移動するという点でメモリ管理全体の最適化がすでに行われているため、これはこの比較的まれなケースの最適化としては機能しません断片化を減らすために、ギャップがある場合はその位置に配置します。配列を固定すると、物を移動する効率が低下するため、配列が移動する可能性が高くなります(配列の前に少しスペースを空けないように強制したため)。

アレイがLOH上にある場合は、使用されなかった後のスペースである可能性が高くなりますが、解放された可能性は低くなります。

したがって、この種のre-mallocは理論的には機能する場合がありますが、特定の時間に機能する確率は小さすぎて、実装する価値がありません。

于 2012-08-13T16:04:03.477 に答える