Sind Java DirectByteBuffer Wrapper-Müll gesammelt?

9

Ich verstehe, dass wenn ein Directbyte-Puffer zugewiesen wird, dieser nicht der Garbage Collection unterliegt, aber was ich mich frage ist, ob das Wrapping Objekt Garbage Collected ist.

Wenn ich beispielsweise einen neuen DirectByteBuffer dbb zugewiesen habe und ihn dann mit dbb.duplicate () dupliziere (seicht kopiere), hätte ich zwei Wrapper um denselben Speicherbereich.

Werden diese Wrapper einer Speicherbereinigung unterzogen? Wenn ich es tat

%Vor%

Würde ich schließlich selbst OOM?

    
Li Pi 14.07.2011, 17:51
quelle

4 Antworten

11

Im Sun JDK ist ein java.nio.DirectByteBuffer -created von ByteBuffer#allocateDirect(int) - hat ein Feld vom Typ sun.misc.Cleaner , das %Co_de% .

Wenn dieser java.lang.ref.PhantomReference (denken Sie daran, ein Untertyp von Cleaner ) gesammelt wird und sich gerade in den zugehörigen PhantomReference bewegt, wird der Sammlungs-Thread, der den geschachtelten Typ ReferenceQueue durchläuft, eine Sonderbehandlung durchlaufen von ReferenceHandler instances: Es sinkt und ruft Cleaner auf, was schließlich zurück zum Aufruf von Cleaner#clean() führt, was wiederum DirectByteBuffer$Deallocator#run() aufruft. Wow.

Es ist ziemlich umständlich und ich war überrascht, keine Verwendung von Unsafe#freeMemory(long) im Spiel zu sehen. Die Sun-Entwickler müssen ihre Gründe haben, dies noch enger mit dem Sammlungs- und Referenzmanagement-Subsystem zu verbinden.

Kurz gesagt, wird Ihnen nicht der Speicher ausgehen, da Verweise auf Object#finalize() -Instanzen aufgegeben werden, solange der Garbage Collector eine Chance hat, den Abbruch zu bemerken, und sein Referenzhandlingthread durch die oben beschriebenen Aufrufe Fortschritte macht .

    
seh 14.07.2011, 19:40
quelle
2

Ein direktes ByteBuffer -Objekt ist genau wie jedes andere Objekt: Es kann Müll-gesammelt werden.

Der von einem direkten Puffer verwendete Speicher wird freigegeben, wenn das ByteBuffer -Objekt GC'd ist (dies ist nicht explizit für ByteBuffer angegeben, wird aber von der Dokumentation von MappedByteBuffer impliziert).

Wo es interessant wird, ist, wenn Sie Ihren virtuellen Speicherbereich mit direkten Puffern gefüllt haben, aber immer noch viel Platz im Heap haben. Es stellt sich heraus, dass (zumindest auf der Sun JVM) das Auslaufen von virtuellem Speicherplatz beim Zuweisen eines direkten Puffers einen GC des Java Heaps auslösen wird. Das kann nicht referenzierte direkte Puffer sammeln und ihre virtuelle Speicherverpflichtung freigeben.

Wenn Sie auf einem 64-Bit-Rechner arbeiten, sollten Sie -XX:MaxDirectMemorySize verwenden, wodurch die Anzahl der Puffer, die Sie zuweisen können, begrenzt ist (und auch GC auslöst, wenn Sie dieses Limit erreichen).

    
parsifal 14.07.2011 19:01
quelle
1

Wenn Sie den Quellcode auf DirectByteBuffer ansehen, wird nur eine neue Instanz zurückgegeben, also nein, Sie werden sich nicht selbst abmelden.

Solange der Rest Ihres Codes keinen Verweis auf das ursprüngliche dbb enthält, wird das Objekt wie üblich als Garbage Collection erfasst. Die zusätzlichen dbb2 -Objekte werden in ähnlicher Weise Garbage Collected erhalten, wenn es keinen Verweis mehr auf sie gibt (dh das Ende der while-Schleife).

    
agxs 14.07.2011 17:57
quelle
-2
  

Wenn ein Directbyte-Puffer zugeordnet ist, unterliegt er nicht dem Müll   Sammlung

Woher hast du diese Idee? Das ist nicht richtig. Hast du sie mit MappedByteBuffers durcheinander gebracht?

    
EJP 15.07.2011 01:00
quelle