2011-07-14 12 views
8

ダイレクトバッファバッファが割り当てられているときにガベージコレクションの対象ではないが、ラッピングオブジェクトがガベージコレクトされていると私は思っています。Java DirectByteBufferラッパーはガベージコレクションされていますか?

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

これらのラッパーはガベージコレクション対象ですか?私がした場合

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

私は結局OOM自分ですか?

+0

実際、DirectByteBufferとそのネイティブメモリはガベージコレクションされます。 PhantomReferenceを使用してネイティブの割り当てられたメモリを解放します。 –

答えて

10

ByteBuffer#allocateDirect(int) —によって作成java.nio.DirectByteBuffer —はjava.lang.ref.PhantomReferenceを拡張タイプsun.misc.Cleanerのフィールドを、有しています。

このCleanerが(PhantomReferenceのサブタイプを覚えている)を収集し、関連ReferenceQueueに移動しようとしている取得したときに、ネストされたタイプReferenceHandler通るコレクション関連スレッドがCleanerインスタンスの特殊なケース処理を有する:それはダウンキャストとCleaner#clean()を呼び出し、最終的にDirectByteBuffer$Deallocator#run()を呼び出すことに戻ります。これは、Unsafe#freeMemory(long)を呼び出します。ワオ。

これはやや円滑で、Object#finalize()の使用は見られないと私は驚きました。 Sunの開発者は、これをコレクションと参照管理のサブシステムにさらに近づける理由を持っていなければなりませんでした。

つまり、ガベージコレクタが放棄に気付く可能性があり、その参照処理スレッドが上記の呼び出しによって進捗している限り、DirectByteBufferインスタンスへの参照を放棄することでメモリが不足することはありません。directbytebufferが割り当てられている

+2

'-XX:+ DisableExplicitGC'を使用している場合、' allocateDirect'でより多くの 'OutOfMemory'エラーが発生する可能性があることに注意してください。 'PhantomReference'の回収をトリガーすることができない場合、割り当てはメモリを予約しようとし、' System.gc() 'を呼び出します。 –

1

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

残りのコードが元のdbbへの参照を保持していない限り、そのオブジェクトは通常どおりガベージコレクトされます。追加のdbb2オブジェクトは、もはやそれらへの参照がなくなったとき(つまり、whileループの終了時)にガベージコレクションされます。

2

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

直接バッファによって使用されるメモリは(これは明示的ByteBufferに関して記載されていないが、MappedByteBufferの文書によって暗示されている)ByteBufferオブジェクトがGC'dときに放出されるであろう。

ここで興味深いのは、仮想メモリ空​​間を直接バッファで満たしたが、ヒープにまだ十分な空き容量があることです。直接バッファを割り当てるときに仮想空間を使い果たしてしまうと(少なくともSun JVM上で)、JavaヒープのGCがトリガーされることが分かります。参照されないダイレクトバッファを収集し、その仮想メモリのコミットメントを解放する可能性があります。

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

+0

DirectByteBuffersを使用すると、TerraCottaのBigMemoryのようなガベージコレクションの一時停止にどのように役立ちますか? –

+0

@ Li Pi:多くのシリアライズされたJavaオブジェクトを1つのダイレクトバッファに格納できるためです。 – parsifal

-2

、ガーベジコレクション

への対象ではないどこでそのアイデアを得るのですか?それは正しくありません。あなたはそれらをMappedByteBuffersと混同していますか?

+0

@downvoterなぜですか? – EJP

関連する問題