Staram się zrozumieć dokumentację sun.misc.Unsafe - jak sądzę, ponieważ nie jest ona przeznaczona do ogólnego użytku, nikt naprawdę nie zadał sobie trudu, żeby ją odczytać - ale naprawdę potrzebuję sposobu na znalezienie adresu element w tablicy (tak, że mogę przekazać do niego wskaźnik na kod natywny). Czy ktoś ma działający kod, który to robi? Czy to jest niezawodne?Użycie adresu sun.misc.Unsafe w celu uzyskania adresu elementów tablicy Java?
Odpowiedz
Zamiast korzystać z tablicy można użyć bezpośredniego bufora ByteBuffer.allocateDirect(). Ma on adres w polu i adres ten nie zmienia się przez cały okres istnienia Bajtowego Buźka. Bezpośredni ByteBuffer wykorzystuje minimalną przestrzeń sterty. Możesz uzyskać adres za pomocą refleksji.
Możesz użyć Unsafe, aby uzyskać adres, problem polega na tym, że GC może go przenieść w dowolnym momencie. Obiekty nie są naprawiane w pamięci.
W JNI można użyć specjalnych metod do kopiowania danych do/z obiektów Java, aby uniknąć tego problemu (i innych) Proponuję użyć ich, jeśli chcesz wymieniać dane między obiektami z kodem C.
Wolałbym nie używać bezpośredniego bufora bajtowego (co raczej ułatwiłoby rozwiązywanie problemu), ponieważ utknąłem próbując zaimplementować istniejący interfejs API, który jest zdefiniowany w kategoriach tablic bajtowych, i próbuję uniknąć kary kopiowania do i z dodatkowego zestawu buforów. To wystarczy jako ostateczność, ale musi istnieć jakiś lepszy sposób. Praca z JNI ułatwiłaby to, ale niestety pracuję z JNA, która nie ma interfejsów niezbędnych do zrobienia czegoś innego niż praca z całymi tablicami. – Jules
@ Jules, JNI spowoduje kopię samodzielnie, chyba że chcesz iść w/"GetPrimitiveArrayCritical", które mogą zranić GC. Ugryź punktor i skopiuj do pamięci bezpośredniej (bufor). To jedyne możliwe rozwiązanie. Na przykład impl. FileOutputStream (SocketOutputStream rozszerza go) używa kopii elementów na stosie. Kara za kopiowanie nie jest tak wysoka, ponieważ najwyższy koszt pochodzi z kosztu ładowania danych (i nawet z pamięci podręcznej), które musiałbyś zapłacić w dowolny sposób. Kopiowanie spowoduje również wstępne pobranie cachelines, więc może być jeszcze lepiej odrzucić sposób działania natywnego kodu. – bestsss
@Jules, na marginesie: nawet javax.net.ssl.SSLEngine pozwala na użycie buforów, wszystkie algorytmy są bajtowe [] i kończą kopiowanie bezpośrednich buforów do tymczasowych tablic, jest to odwrotna historia i morał tego : nie używaj bezpośrednich buforów w/SSLEngine. – bestsss
Oto działająca próbka. Należy jednak zachować ostrożność, ponieważ może to łatwo spowodować awarię maszyny JVM przy niewłaściwym użytkowaniu klasy Unsafe
.
import java.lang.reflect.Field;
import sun.misc.Unsafe;
public class UnsafeTest {
public static void main(String... args) {
Unsafe unsafe = null;
try {
Field field = sun.misc.Unsafe.class.getDeclaredField("theUnsafe");
field.setAccessible(true);
unsafe = (sun.misc.Unsafe) field.get(null);
} catch (Exception e) {
throw new AssertionError(e);
}
int ten = 10;
byte size = 1;
long mem = unsafe.allocateMemory(size);
unsafe.putAddress(mem, ten);
long readValue = unsafe.getAddress(mem);
System.out.println("Val: " + readValue);
}
}
Ten kod musi być całkowicie bezpieczny, ponieważ dokładnie działa DirectByteBuffer. Niestety nie robi tego, co chcę, czyli dostępu do danych w istniejącej macierzy. – Jules
@StephenC, kod jest całkowicie w porządku, to w zasadzie 'char * mem = malloc (rozmiar); ...' nigdy nie jest dotykany przez GC i powoduje natywny wyciek C, chyba że zostanie wyrealizowany. – bestsss
Kod jest w porządku, ale należy również rozważyć zwolnienie przydzielonej pamięci. Zobacz DirectByteBuffer dla jednego sposobu robienia tego. Weź również pod uwagę, że przydzielona pamięć nie jest wyzerowana, więc nie można założyć, że twoja bezpośrednia tablica jest zerowana. –
Dlaczego? W JNI dostępnych jest wiele narzędzi do radzenia sobie z zawartością tablic Java. Nie musisz korzystać z nieudokumentowanych wewnętrznych klas Sun, których może nie być w przyszłym tygodniu.
- 1. Polecenie powłoki w celu uzyskania adresu mac w OS X
- 2. Przekazywanie tablicy do adresu URLSearchParams podczas korzystania z połączenia HTTP w celu uzyskania żądania
- 3. Jak aplikacja Java WebStart Uzyskiwanie adresu MAC w celu uzyskania dostępu do mojej strony internetowej
- 4. Korzystanie z System.Net.WebClient w PowerShell w celu uzyskania dostępu do adresu URL HTTPS z certyfikatem SAN
- 5. Wyrażenie regularne w celu uzyskania adresu URL w ciągi swift z symbolami pisanymi wielkimi literami
- 6. Ustaw właściwość src w celu uzyskania adresu URL spoza projektu MVC3
- 7. R: Użycie pakietu rvest zamiast pakietu XML do uzyskania linków z adresu URL
- 8. Obrazek do tablicy bajtów z adresu URL
- 9. Grupa wzorów/Matchera() w celu uzyskania podciągu w języku Java?
- 10. Używanie interfejsu Google Maps API do uzyskania adresu firmy
- 11. OpenID: próba uzyskania adresu e-mail z Google OP
- 12. Polecenie adb do uzyskania adresu IP przydzielonego przez operatora
- 13. WCF: System.Net.SocketException - dozwolone jest tylko jedno użycie każdego adresu gniazda (protokołu/adresu sieciowego/portu)
- 14. Sprawdzanie poprawności jquery w celu sprawdzenia poprawności adresu URL
- 15. Dodawanie adresu bazowego + odsunięć w celu modyfikacji wartości
- 16. Jak naprawić błąd "Tylko jedno użycie każdego adresu gniazda (protokołu/adresu sieciowego/portu) jest normalnie dozwolone"?
- 17. Android/Java: Zaokrąglanie numeru w celu uzyskania wartości dziesiętnej
- 18. Zamiana pozycji elementów w tablicy w java?
- 19. Uzyskiwanie lokalnego adresu IP
- 20. Asynchroniczna rozdzielczość adresu w winsock?
- 21. Zdobądź domenę drugiego poziomu adresu URL (java)
- 22. Użycie polecenia typeedef dla tablicy w celu zadeklarowania nowego typu
- 23. Java/Wiosna MVC 3 walidacja adresu email
- 24. Java HttpServletRequest uzyskać adres URL w przeglądarce Pasek adresu URL
- 25. Dlaczego powinienem używać adresu url.openStream zamiast adresu url.getContent?
- 26. Google API/OAuth - jak korzystać z adresu e-mail [email protected] w celu uzyskania informacji o marce?
- 27. Składnia dla rezerwacji adresu URL netsh dla dowolnego adresu IP
- 28. Ograniczenie dostępu do adresu monitorowania monitorowania w języku Java
- 29. Znajdowanie adresu IP użytkownika
http://stackoverflow.com/questions/5574241/interesting-uses-of-sun-misc-unsafe –
[Dlaczego deweloperzy nie powinni pisać programów To wywołaj pakiety "słońce"] (http://www.oracle .com/technetwork/java/faq-sun-packages-142232.html) – BalusC
imo, niebezpieczny dokument jest całkiem niezły, nie jest przeznaczony dla ogółu społeczeństwa. jeśli potrzebujesz pewnych wskazówek, zacznij czytać java.util.concurrent i java.util.concurrent.atomic ... niebezpieczne jest całkiem blisko C (lub asemblera, jeśli wolisz). Jeśli nie masz żadnego doświadczenia, jeśli nie, niebezpieczne nie jest dla ciebie. Jak zdemontować kod Java: http://wikis.sun.com/display/HotSpotInternals/PrintAssembly – bestsss