Estoy luchando por comprender la documentación de sun.misc.Unsafe - supongo que no es para uso general, nadie se molesta en hacerlo legible, pero en realidad necesito una forma de encontrar la dirección de un elemento en una matriz (para que pueda pasarle un puntero al código nativo). Alguien tiene un código de trabajo que hace esto? ¿Es confiable?Uso de sun.misc.Unsafe para obtener la dirección de los elementos de la matriz de Java?
Respuesta
En lugar de utilizar una matriz, puede utilizar un búfer directo ByteBuffer.allocateDirect(). Esto tiene la dirección en un campo y esta dirección no cambia durante la vida del ByteBuffer. Un ByteBuffer directo utiliza un espacio de montón mínimo. Puede obtener la dirección usando reflexión.
Puede utilizar Unsafe para obtener una dirección, el problema es que el GC puede moverlo en cualquier momento. Los objetos no están arreglados en la memoria.
En JNI puede usar métodos especiales para copiar datos en/desde objetos Java para evitar este problema (y otros) Sugiero que los use si desea intercambiar datos entre Objetos con código C.
Prefiero no usar un búfer de byte directo (lo que haría la solución del problema bastante fácil) ya que estoy atascado tratando de implementar una API existente que se define en términos de matrices de bytes, y estoy tratando de evitar la penalización de copiar a y de un conjunto extra de búferes. Esto sería suficiente como último recurso, pero debe haber una forma mejor. Trabajar con JNI lo haría más fácil, pero desafortunadamente estoy trabajando con JNA, que no parece tener las interfaces necesarias para hacer otra cosa que no sea trabajar con arreglos completos. – Jules
@Jules, JNI causará una copia por sí mismo, a menos que desee ir con w/'GetPrimitiveArrayCritical', lo que podría dañar el GC. Muerde la bala y copia en la memoria directa (buffer). Esa es la única solución factible. Por ejemplo, el Impl. FileOutputStream (SocketOutputStream lo extiende) usa una copia de los elementos en la pila. La multa por copiar no es tan alta, ya que el costo más alto se obtiene con el costo de carga de los datos (y el caché falla, incluso) que tendría que pagar de cualquier manera. La copia también provocará la captación previa de las líneas de caché, por lo que podría ser incluso mejor implementar cómo funciona el código nativo. – bestsss
@Jules, en una nota al margen: incluso javax.net.ssl.SSLEngine permite el uso de búferes, todos los algoritmos son byte [] y terminan copiando búferes directos en matrices temporales, esta es la historia inversa y la moraleja de esto : no use búferes directos con SSLEngine. – bestsss
Aquí hay una muestra de trabajo. Sin embargo, tenga cuidado ya que puede bloquear fácilmente su JVM con un uso inapropiado de la clase 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);
}
}
Ese código debe ser perfectamente seguro, ya que es exactamente como funciona DirectByteBuffer. Lamentablemente, no hace lo que quiero, que es acceder a los datos en una matriz existente. – Jules
@StephenC, el código está perfectamente bien, es básicamente 'char * mem = malloc (tamaño); ...' nunca es tocado por el GC y causa una fuga de C nativa a menos que se restablezca. – bestsss
El código está bien, pero también debe considerar liberar la memoria asignada. Vea DirectByteBuffer para una forma de hacerlo. Tenga en cuenta también que la memoria asignada no está puesta a cero, por lo que no puede suponer que su matriz directa se inicializa en cero. –
¿Por qué? Hay muchas instalaciones en JNI para tratar con los contenidos de las matrices de Java. No necesita usar clases Sun internas no documentadas que podrían no estar allí la próxima semana.
Estoy usando JNA, en lugar de JNI, y la función con la que estoy interactuando necesita tener un puntero pasado al centro de una matriz, mientras que JNA solo parece ser capaz de producir un puntero al inicio de una matriz. – Jules
@Jules, no mezcle JNA y arreglos normales, use búferes directos. – bestsss
- 1. Dirección de la matriz
- 2. Obtener la dirección IP de los visitantes
- 3. ¿Cómo obtengo la dirección de los elementos en una matriz char?
- 4. ¿Cómo obtener la dirección de memoria del montón de Java?
- 5. Cómo obtener la dirección de la brújula
- 6. Obtener la dirección IP 'externa' en Java
- 7. cómo obtener la dirección de memoria de una matriz numpy para C
- 8. Ordenar elementos de la matriz
- 9. Obtener la dirección de la instrucción actual para x86
- 10. Escriba check en todos los elementos de la matriz
- 11. cómo eliminar elementos de la matriz?
- 12. ¿Estructura de datos de Java para la matriz?
- 13. Obtener todos los elementos, pero el primero de una matriz
- 14. elementos de la matriz de ref
- 15. ¿Cuál es la mejor manera de obtener los últimos N elementos de una matriz Perl?
- 16. Obtener latitud y longitud desde la dirección sin el uso de la API de Google
- 17. ¿Intercambia la posición de los elementos dentro de una matriz en java?
- 18. matriz Uno de los elementos de estructura
- 19. elemento de la matriz envolver todos los elementos
- 20. Obtener la longitud de la matriz de una matriz 2D en Java
- 21. Obtener la dirección IP con la cadena URL? (Java)
- 22. obtener la dirección de un objeto lua
- 23. jQuery función para obtener todos los elementos únicos de una matriz?
- 24. Obtener dirección MAC en la máquina local con Java
- 25. Java: forma correcta de obtener la clase de una matriz primitiva para la reflexión
- 26. LINQ - la propiedad de matriz contiene elementos de otra matriz
- 27. Eliminando elementos de la matriz Ruby
- 28. Cómo obtener la dirección IP de sockaddr
- 29. Encuentra la ventana más pequeña de la matriz de entrada que contiene todos los elementos de la matriz de consulta
- 30. R: ¿cómo obtener los nombres de fila y columna de los elementos verdaderos de una matriz?
http://stackoverflow.com/questions/5574241/interesting-uses-of-sun-misc-unsafe –
[Por qué los desarrolladores no deben escribir programas That Call 'sun' Packages] (http://www.oracle .com/technetwork/java/faq-sun-packages-142232.html) – BalusC
imo, el documento inseguro es bastante bueno, de todos modos no está destinado al público en general. si necesita algunas pautas, comience a leer java.util.concurrent y java.util.concurrent.atomic ... inseguro es bastante cercano a C (o ensamblador, si lo prefiere). Si no tiene ninguna experiencia, no es seguro para usted. Cómo obtener el desmontaje de su código java: http://wikis.sun.com/display/HotSpotInternals/PrintAssembly – bestsss