2013-05-09 15 views
6

Czy muszę mieć funkcję pomocnika JNI, która wywołuje env-> NewDirectByteBuffer (bufor, rozmiar)?Czy istnieje sposób na utworzenie bezpośredniego obiektu ByteBuffer ze wskaźnika wyłącznie w języku Java?

+1

Pan spojrzał na sun.misc.unsafe? Pozwala na bezpośrednią interakcję z pamięcią. – assylias

+0

Zerknąłem i nie widziałem sposobu na utworzenie bezpośredniego bufora bajtowego z sun.misc.unsafe. Znalazłem sposób na stworzenie DirectByteBuffer i to poprzez odbicie. Użyj java.lang.Class.getDeclaredConstructor, aby utworzyć obiekt Constructor, setAccessable na wartość true i wywołaj newInstance z odpowiednimi parametrami. Trochę jane, ale nie musisz pisać kodu JNI. –

Odpowiedz

15

Co mogę zrobić, to stworzyć normalny DirectByteBuffer i zmienić jego adres.

Field address = Buffer.class.getDeclaredField("address"); 
address.setAccessible(true); 
Field capacity = Buffer.class.getDeclaredField("capacity"); 
capacity.setAccessible(true); 

ByteBuffer bb = ByteBuffer.allocateDirect(0).order(ByteOrder.nativeOrder()); 
address.setLong(bb, addressYouWantToSet); 
capacity.setInt(bb, theSizeOf); 

Od tego momentu można uzyskać dostęp do ByteBuffer odwołującego się do adresu bazowego. Zrobiłem to dla dostępu do pamięci na kartach sieciowych dla zerowej kopii i działało dobrze.

Możesz utworzyć DirectByteBuffer dla swojego adresu bezpośrednio, ale jest to bardziej niejasne.


Alternatywą jest użycie niebezpiecznych (ten działa tylko na OpenJDK/HotSpot JVMs w natywnej kolejności bajtów)

Unsafe.getByte(address); 
Unsafe.getShort(address); 
Unsafe.getInt(address); 
Unsafe.getLong(address); 
+0

Świetna odpowiedź, jednak musiałem ją zhakować, aby działało, szczególnie Field address = Buffer.class.getDeclaredField ("address"). – Erik

+0

@Erik dziękuję za korektę. –

+0

Oto więc kontynuacja pierwotnego pytania, ponieważ wciąż zwracasz uwagę. Jaki jest najlepszy sposób na wyczyszczenie pamięci dołączonej do ByteBuffer w ten sposób? Czy ByteBuffer sfinalizuje bezpłatny adres, czy powinien zadzwonić internauci i wyczyścić alokację? Dla celów tego pytania załóżmy, że napisałem bibliotekę JNI z owijkami wokół malloc i wolnymi :) Prawdopodobnie zasługuje na to własne pytanie, teraz, gdy myślałem o tym więcej. – Erik

Powiązane problemy