15

directbytebufferが割り当てられると、ガベージコレクションの対象にならないことは理解していますが、ラッピングオブジェクトがガベージコレクションであるかどうかは疑問です。

たとえば、新しいDirectByteBuffer dbbを割り当て、dbb.duplicate()を使用して複製(浅いコピー)した場合、同じメモリチャンクの周りに2つのラッパーがあります。

それらのラッパーはガベージコレクションの対象になりますか?私がやったら

while(true){
    DirectByteBuffer dbb2 = dbb.duplicate();
} 

私は最終的に自分自身をOOMしますか?

4

4 に答える 4

18

Sun JDKでは、java.nio.DirectByteBuffer-によって作成された-には、を拡張ByteBuffer#allocateDirect(int)するタイプのフィールドがあります。sun.misc.Cleanerjava.lang.ref.PhantomReference

これCleaner(のサブタイプを思い出してくださいPhantomReference)が収集され、関連付けられたに移動しようとするとReferenceQueue、ネストされたタイプを実行するコレクション関連のスレッドは、インスタンスReferenceHandlerの特殊なケース処理を行います。を呼び出すために、次にを呼び出します。わお。CleanerCleaner#clean()DirectByteBuffer$Deallocator#run()Unsafe#freeMemory(long)

それはかなり遠回りであり、私は場での使用が見られないことに驚いたObject#finalize()。Sunの開発者は、これをコレクションおよび参照管理サブシステムにさらに近づける理由があったに違いありません。

DirectByteBufferつまり、ガベージコレクターが放棄に気付く機会があり、その参照処理スレッドが上記の呼び出しを進めている限り、インスタンスへの参照を放棄してもメモリが不足することはありません。

于 2011-07-14T19:40:23.347 に答える
4

直接ByteBufferオブジェクトは他のオブジェクトとまったく同じです。ガベージコレクションを行うことができます。

直接バッファによって使用されるメモリは、ByteBufferオブジェクトがGCされると解放されます(これは、について明示的には述べられていませんByteBufferが、のドキュメントによって暗示されていますMappedByteBuffer)。

興味深いのは、仮想メモリスペースを直接バッファで埋めたが、ヒープに十分なスペースがある場合です。(少なくともSun JVMでは)直接バッファーを割り当てるときに仮想スペースが不足すると、JavaヒープのGCがトリガーされることがわかりました。これにより、参照されていない直接バッファが収集され、仮想メモリのコミットメントが解放される可能性があります。

64ビットマシンで実行している場合は、を使用する必要があります-XX:MaxDirectMemorySize。これにより、割り当てることができるバッファーの数に上限が設定されます(また、その制限に達するとGCがトリガーされます)。

于 2011-07-14T19:01:40.293 に答える
1

ソースコードを見るとDirectByteBuffer、新しいインスタンスが返されるだけなので、いいえ、自分でOOMすることはありません。

コードの残りの部分が元のコードへの参照を保持しない限り、dbbそのオブジェクトは通常どおりガベージコレクションされます。余分なdbb2オブジェクトは、それらへの参照がなくなると(つまり、whileループの終わり)、同様にガベージコレクションされます。

于 2011-07-14T17:57:20.927 に答える
-2

directbytebufferが割り当てられている場合、ガベージコレクションの対象にはなりません

どこでそのアイデアを思いついたのですか?正しくありません。それらをMappedByteBuffersと混同していませんか?

于 2011-07-15T01:00:42.720 に答える