8

ガベージコレクションされたヒープから要素の配列を割り当て、生のポインターを介してのみそれらの要素にアクセスしたいと思います。ガベージコレクターは、それを指すために使用されたすべてのポインターがスコープ外になった後(前ではなく)にそのメモリブロックを再利用できますか?

私はこのようにすることを考えていました:

{
    int* ptrToArray1 = (new int[](100)).ptr;
    int* ptrToArray2 = ptrToArray1;
    int* ptrToArray3 = ptrToArray1 + 10;

    ptrToArray1 += 50;
    ptrToArray2 += 99;

    *ptrToArray1 = 123;
    *ptrToArray2 = 456;
    *ptrToArray3 = 789;

    ptrToArray1 -= 42;
    ptrToArray2 -= 24;

    //... and so on ... Is the array data guaranteed to be there?
}
// Now that all the pointers are out of scope, can the
// garbage collector reclaim the memory block of that array?
4

1 に答える 1

14

あなたのシナリオはうまくいくでしょう。

2つのこと:

  1. ガベージコレクターは保守的です。つまり、スタック、レジスタ、およびGCヒープの生のワードをスキャンします。GCに割り当てられたメモリへのポインタのように見えるものはすべてそのようなものと見なされるため、そのメモリを存続させます。
  2. ガベージコレクターは内部ポインターを許可します。この理由は2つあります。まず、(システム言語では)ポインタ演算だけを使用してrawメモリを反復処理するのはかなり一般的であるため、GCは、オフセットポインタのみがGCメモリを指すような状況を処理する必要があります。次に、Dのインターフェイスは実際にはベースオブジェクトからのオフセットにすぎないため、元のオブジェクトを存続させる必要があります。

内部ポインタがガベージコレクタのマーキングフェーズを大幅に遅くすることは注目に値しますが、Dのようなシステム言語では、内部ポインタをサポートしないことは不合理です。

最後に、GCヒープおよびスタック/レジスタの外部にあるGC割り当てメモリへのポインタを格納すると、GCによって取得されないことに注意してください。つまり、いくつかの配列.ptrをいくつかmallocのメモリに格納し、それへのすべての参照を破棄した場合、たとえば、その配列はライブとは見なされません。

于 2012-08-30T08:23:45.490 に答える