Wofür benötigt man ByteBuffer?

  • Themenstarter Themenstarter hüteüberhüte
  • Beginndatum Beginndatum
H

hüteüberhüte

Gast
Java:
ByteBuffer bb = ByteBuffer.allocate(262144); // 256 KB

Die Frage ist, wofür man ByteBuffer benötigt, warum er sich z.B. nicht vergrößern lässt und ob es Alternativen gibt. :bahnhof:

Liefert array() dasselbe backing array zurück oder wird kopiert?

Wofür sind die Methoden compact, duplicate und slice?

Wie ist equals, hashCode und compareTo implementiert?
 
Sieh' dir einfach mal die Methoden eines ByteBuffers an, dann wirst du es evtl. schon verstehen. Das wichtigste aber dürfte sein, dass man "ByteArrays" (also keine Arrays im Sinne von Java) mit "allocateDirect()" ausserhalb des Java-Heapspace erstellen kann. Solche Buffer belegen dann Systemspeicher und belasten den Heap nur mit ihren obligatorischen 8 Object- sowie zusätzlichen 8 Längenbytes. Dem aufmerksamen Leser fällt sofort auf, dass ByteBuffer die weitaus besseren Arrays sind.
[EDIT]array() liefert genau jene Instanz des Arrays, welche mit "wrap()" übergeben wurde. Wurde der Buffer mit "allocate()" instanziert bekommt man pro Aufruf ein und die selbe Instanz. Buffer, welche per "allocateDirect()" instanziert wurden haben kein Array und ein Aufruf der Methode "array()" führt zu einer Exception.
"slice()" hab' ich noch nicht verwendet aber mit "duplicate()" bekommt man einen Buffer der zwar das selbe Array wie der Originale hat, jedoch kann man an diesem Pointer, Limits, Inhalt usw. beliebig verändern. An dem Originalen ändert sich bis auf den Inhalt jedoch nichts (vllt. könnte man es als besseres "mark/reset" in InputStreams bezeichnen).[/EDIT]
 
Zuletzt bearbeitet von einem Moderator:
[...] ausserhalb des Java-Heapspace erstellen kann.

Ok, also werden sie gemappt. Der Heapspace wird also nicht so groß. Aber er ist doch im Prinzip viel schneller?

ByteBuffer also nur ein Array-Ersatz (mit Methoden, um z.B. auch int und andere Datentypen hinzuzufügen)?
 
Zuletzt bearbeitet von einem Moderator:
Ok, also werden sie gemappt. Der Heapspace wird also nicht so groß. Aber er ist doch im Prinzip viel schneller?
Irrtum. Gemappte Buffer haben ein Array, wie man es von Java her kennt (mit Overhead und allem). DirectBuffer haben ein solches halt nicht, die Verwaltung des Buffers liegt ausschlieslich auf nativer Seite. Daraus folgt: Nein, der Heap ist keineswegs schneller.
ByteBuffer also nur ein Array-Ersatz (mit Methoden, um z.B. auch int und andere Datentypen hinzuzufügen)?
Alles in allem... siehe Edit... "Ersatz" klingt so "billig", ich würde es als leistungsfähige Ergänzug bezeichnen. Versuch' du mal einem Array den Funktionsumfang eines solchen Buffers zu implementieren, da kommst aber ins schwitzen (Erfahrungswert 😳).
 
Zuletzt bearbeitet von einem Moderator:
Ok, danke. Im ersten Sem. mussten wir auch mal so eine ähnliche Klasse schreiben. Das ist wahrlich keine einfache Aufgabe. 😀

Wer erklärt mir jetzt noch die Methoden? In der API ( ByteBuffer (Java Platform SE 6) ) habe ich schon ein bisschen geguckt, aber wirklich durchgeblickt habe ich bis jetzt noch nicht...
 
Zuletzt bearbeitet von einem Moderator:
Nun, ByteBuffer haben noch wichtigere Eigenschaften und Anwendungsbereiche als die Möglichkeit, die JVM um ein paar MB speicher zu bes******en 😉 Ein ByteBuffer hat einige Eigenschaften, die man sonst nur von C-Pointern her kennt, und kommen diesen in mancher Hinsicht sehr nah. Man kann in einem ByteBuffer auch floats speichern, und sogar "gemischte" primitive Datentypen: Z.B. 3 floats, 2 short und 4 ints in einem ByteBuffer unterbringen. Sowas wie "Memory Mapped Files" sind auch ein Fall, wo man erstmal nur mit ByteBuffern zu tun hat. Man kann damit leicht Daten, die man z.B. aus einer Datei liest, wahlweise als Big- oder Little Endian interpretieren. Sowas wie "slice" bietet außerdem die Möglichkeit, "unter-Buffer" zu definieren (schon fast entsprechend Pointerarithmetik in C, in mancher Hinsicht sogar noch "mächtiger"). Insgesamt gibt es viele stellen, wo sie praktisch sein können.
Ein konkreter Bereich, wo sie sehr häufig eingesetzt werden, ist bei JNI-Wrapper-Bibliotheken für C-Libs. Sowas wie JOGL oder LWJGL verwenden fast überall ByteBuffer/IntBuffer/FloatBuffer, wo man eigentlich byte[]/int[]/float[] erwarten würde: Auf der C-Seite ist der Zugriff auf direct Buffers viel einfacher (und hat einige Glitches NICHT, die es bei normalen Arrays eben gibt). Abgesehen davon kann man auch Speicher, den man in C reserviert hat, in Form eines ByteBuffers nach Java rüberreichen.
 

Zurück
Oben