Prefacio
Este artículo presenta principalmente contenido relevante sobre la clase insegura en Java. Se comparte para su referencia y aprendizaje. No diré mucho a continuación. Echemos un vistazo a la introducción detallada juntos.
1. Introducción de clase insegura
La clase insegura está debajo del paquete Sun.Misc y no pertenece al estándar Java. Sin embargo, muchas bibliotecas de clases básicas de Java, incluidas algunas bibliotecas de desarrollo de alto rendimiento ampliamente utilizadas, se desarrollan en base a una clase insegura, como Netty, Hadoop, Kafka, etc.
Insafe se puede utilizar para acceder directamente a los recursos de memoria del sistema y administrar de forma independiente. La clase insegura juega un gran papel en la mejora de la eficiencia de la operación de Java y la mejora de las capacidades de operación subyacentes del lenguaje Java.
Inseguro puede considerarse una puerta trasera que queda en Java, proporcionando algunas operaciones de bajo nivel, como acceso directo a la memoria, programación de subprocesos, etc.
No se recomienda inseguro.
Aquí hay algunos ejemplos de uso inseguro.
1.1 instanciar una clase privada
import java.lang.reflect.field; importar sun.misc.unsafe; public class UnsafePlayer {public static void main (string [] args) lanza la excepción {// Instanciar campo inseguro f = unsafe.class.getDeclaredfield ("TheunSafe"); F.SetAccessible (verdadero); Inseguro inseguro = (inseguro) f.get (nulo); // Instanciar jugador jugador jugador = (jugador) inseguro.allocateInstance (jugador.class); Player.setName ("Li Lei"); System.out.println (jugador.getName ()); }} Jugador de clase {nombre de cadena privada; Player private () {} public String getName () {name de retorno; } public void setName (nombre de cadena) {this.name = name; }} 1.2 Operación CAC, cambie el valor del medidor a través de la modificación de la dirección de compensación de memoria
Use CAS para actualizar la parte superior de la pila en transferencia en Synchronousqueue en el paquete de concurrencia Java.
/ Inseguro Mecánico Private estático final sun.misc.unsafe inseguro; private static final long fantasfetset; static {try {unsafe = sun.misc.unsafe.getunsafe (); Clase <?> K = transferstack.class; HeadOffSet = Unsafe.ObjectFieldOffset (k.getDeclaredField ("Head")); } catch (Exception e) {tire nuevo error (e); }} // Cabezal volátil de Snode; // Actualiza la parte superior de la pila Boolean Cashead (Snode H, Snode NH) {return h == head && unsafe.compareandswapobject (this, HeadOffset, H, NH);} 1.3 acceso directo a la memoria
Acceso directo a la memoria de Inse Safe: el espacio de memoria abierto con inseguro no ocupa el espacio de montón y, por supuesto, no tiene una función de recuperación de memoria automática. Hacer posible utilizar los recursos de memoria del sistema libremente como C.
2. Análisis de código fuente de clase inseguro
La mayoría de las API de UNSAFE son métodos nativos, principalmente incluyendo las siguientes categorías:
1) Relacionado con la clase. Proporciona principalmente clase y sus métodos de operación de campos estáticos.
2) Objeto relacionado. Principalmente proporciona los métodos de operación de objeto y sus campos.
3) Arrray relacionado. Principalmente proporciona los métodos de operación de matrices y elementos en ellos.
4) Correlación concurrente. Proporciona principalmente primitivas de sincronización de bajo nivel, como CAS, programación de subprocesos, volátil, barrera de memoria, etc.
5) Relacionado con la memoria. Proporciona un método de acceso de memoria directa (sin pasar por el montón de Java y manipulando directamente la memoria local), que puede utilizar libremente recursos de memoria del sistema como C.
6) relacionado con el sistema. Devuelve principalmente alguna información de memoria de bajo nivel, como el tamaño de la dirección y el tamaño de la página de memoria.
2.1 Clase relacionado
// El desplazamiento de los atributos estáticos se usa para leer y escribir los atributos estáticos en el objeto de clase correspondiente público Native Long staticfieldoffset (campo f); Objeto público público staticfieldbase (campo f); // juzga si una clase debe inicializarse públicamente boolean nativo debe ser incluido (clase <?> c); // Asegúrese de que la clase se inicialice publicidad pública national native nationSinitialized (class <?> c); // Definir una clase que puede usarse para crear dinámicamente las clases públicas class de clase <?> ClassLoader Loader, ProtectionDomain ProtectionDomain); // Definir una clase anónima que puede usarse para crear dinámicamente clases de clase pública nativa <?> DefeSeAnyonyMlass (class <?> HostClass, byte [] data, object [] cppatches);
2.2BJECTO RELACIONADO
Existen los siguientes métodos para tipos básicos (booleano, byte, char, short, int, long, float, doble) y tipos de referencia de objetos en Java.
// Obtener la compensación de campo del objeto público Native Long ObjectFieldOffset (campo F); // Obtener el valor int del objeto de objeto dada compensación pública nativa int getint (objeto o, desplazamiento largo); // Establezca el valor int de la dirección de objeto dada compensación pública national nation void putint (objeto o, desplazamiento largo, int x);
// Crear un objeto, pero su constructor no se llamará. Si la clase no se inicializa, la clase se inicializa. Public Native Object AssocateInstance (clase <?> CLS) lanza InstanciationException;
2.3 Relacionado con la matriz
/** * Informe el desplazamiento del primer elemento en la asignación de almacenamiento de una clase de matriz dada. Si {@link #ArrayIndexscale} devuelve un valor distinto de cero * para la misma clase, puede usar ese factor de escala, junto con este * desplazamiento base, para formar nuevas compensaciones para acceder a elementos de matrices de la clase * dada. * * @see #getInt (Object, Long, int) * /// Devuelve la dirección de desplazamiento del primer elemento en la matriz public nation int ArrayBaseOffset (class <?> ArrayClass); // boolean, byte, short, char, int, long, float, double y objetos tienen los siguientes métodos/** el valor de {@code arraybaseffset (boolean []. Array_boolean_base_offset = theunSafe.ArrayBaseOffset (boolean []. Class); /** * Informe el factor de escala para abordar los elementos en la asignación de almacenamiento * de una clase de matriz determinada. Sin embargo, las matrices de tipos "estrechos" * generalmente no funcionarán correctamente con accesores como {@link * #getbyte (objeto, int)}, por lo que el factor de escala para tales clases se informa * como cero. * * @see #arraybaseffset * @see #getint (objeto, long) * @see #putint (objeto, long, int) * /// Devuelve el tamaño ocupado por cada elemento en la matriz pública nativa int Arrayindexscale (class <?> ArrayClass); // Los tipos de boolean, byte, short, char, int, long, float, double y objetos tienen los siguientes métodos/** El valor de {@code arrayIndexscale (boolean []. class)}*/public static final int array_boolean_index_scale = theunsafe.arrayindexscale (boolean []. class); La ubicación de cada elemento en la matriz en la memoria se puede ubicar a través de ArrayBaseffset y ArrayIndexscale.
2.4 Relacionado con concurrencia
2.4.1 CACS RELACIONADO
CAS: Compareandswap, compensación de la dirección de desplazamiento de memoria, valor esperado esperado, nuevo valor x. Si el valor de la variable en la hora actual y el valor esperado es igual, intente actualizar el valor de la variable a x. Devolver verdadero si la actualización es exitosa; De lo contrario, devuelva falso.
// Actualizar el valor variable en x, si se espera el valor actual // o: Offset de objeto: Offset esperado: Valor esperado X: Nuevo valor público Public final Native Booleanswapobject (objeto o, desplazamiento largo, objeto esperado, objeto x); Público final Native Boolean Compareandswapint (Object O, Long Offset, int esperado, int x); Público Final Final Boolean Compareandswaplong (objeto O, desplazamiento largo, larga esperada, larga x);
Comenzando con Java 8, los siguientes métodos se proporcionan en inseguro:
// Agregar público final int getandaddint (objeto o, desplazamiento largo, int delta) {int v; do {v = getIntVolatile (o, offset); } while (! compareanddswapint (o, offset, v, v + delta)); return v;} pública final larga getandaddlong (objeto o, desplazamiento largo, delta largo) {long v; do {v = getLongVolatile (o, offset); } while (! compareanddswaplong (o, offset, v, v + delta)); return v;} // establecer public final int getAndSetInt (objeto o, desplazamiento largo, int newValue) {int v; do {v = getIntValatile (o, offset); } while (! compareanddswapint (o, offset, v, newValue)); return v;} pública final long getandsetlong (objeto o, desplazamiento largo, largo newValue) {long v; do {v = getLongValatile (o, offset); } while (! compareanddswaplong (o, offset, v, newValue)); return v;} public Final Object GetAndSetObject (objeto o, desplazamiento largo, objeto newValue) {objeto v; do {v = getObjectValatile (o, offset); } while (! compareanddswapobject (o, offset, v, newValue)); regreso v;2.4.2 Relacionado con la programación de hilos
// Desbloqueo de hilo público Native void Unpark (hilo de objeto); // Bloqueo de hilo público Native void Park (boolean isabsolute, largo tiempo); // Obtener bloqueo de objeto Public Native Native Void MonitorEenter (Object O); // Libere de liberación de objeto Public Native Void MonitorExit (Object O) ;// Intenta obtener el bloqueo de objeto, regresa verdadero o falso para indicar si es exitoso público Native Trymonitorenteriter (Object OBJETIVE (OBJETO);
2.4.3 Lectura y escritura relacionadas con volátiles
Existen los siguientes métodos para tipos básicos (booleano, byte, char, short, int, long, float, doble) y tipos de referencia de objetos en Java.
// Obtenga la referencia de la variable del desplazamiento especificado del objeto y use la semántica de carga de volátil // equivalente a la versión volátil de getObject (objeto, largo) objeto nativo público getObjectVolatile (objeto o, desplazamiento largo); // Almacenamiento La referencia de la variable a la compensación especificada del objeto y use la semántica de almacenamiento de volátil // equivalente a la versión volátil de Putobject (objeto, largo, objeto) público void nativo PutobjectVolatile (objeto o, desplazamiento largo, objeto x);
/** * Versión de {@link #putObjectVolatile (objeto, largo, objeto)} * que no garantiza la visibilidad inmediata de la tienda a * otros hilos. Este método generalmente solo es útil si el * campo subyacente es un Java Volátil (o si una celda de matriz, una * a la que de otro modo solo se accede utilizando accesos volátiles). */public nation native putorderedObject (objeto o, desplazamiento largo, objeto x); /** Versión ordenada/perezosa de {@link #putIntVolatile (objeto, long, int)}*/public nation void putorderedInt (objeto o, desplazamiento largo, int x); /** Versión ordenada/perezosa de {@link #putLongVolatile (objeto, largo, largo)}*/public nation void putorderedlong (objeto o, desplazamiento largo, largo x);2.4.4 Barrera de memoria relacionada con
Java 8 se introdujo para definir las barreras de memoria para evitar el reordenamiento del código.
// La barrera de memoria, prohíbe que las operaciones de carga se reordenen, es decir, las operaciones de carga antes de que la barrera no se pueda reordenar a la barrera, las operaciones de carga después de que la barrera no se puede reordenar al frente de la barrera pública Native nation void loadfence (); // Barrera de memoria, prohíbe las operaciones de memoria de la tienda, prohíbe la barrera de la tienda de la tienda, la barrera nativa, la barrera nativa (); Cargar y almacenar las operaciones desde ser reordenadas al frente de la barrera pública Native nation void fullfence ();
2.5 Acceso a la memoria directa (memoria sin montón)
La memoria asignada por Allocatememorio debe ser gratuita manualmente (no reciclada por GC)
// (booleano, byte, char, short, int, long, float, double) tienen los siguientes dos métodos: obtener y poner. // Obtenga el valor INT en la dirección dada Public Native int // Asignar memoria pública pública Native Long AllocateMemory (bytes largos); // REALELOCE MEMORIA PÚBLICA PUBLICA REALELOCTEMEMEMORY (dirección larga, bytes largos); // Inicializar el contenido de memoria Public Native void setMemory (objeto O, largo descenso, bytes largos, valor de byte); // Inicializar el contenido de memoria Public okmemory (dirección larga, larga bytes, valor de teja) address, bytes, value);}//Initialize the memory content public native void copyMemory(Object srcBase, long srcOffset, Object destBase, long destOffset, long bytes);//Initialize the memory content public void copyMemory(long srcAddress, long destAddress, long bytes) { copyMemory(null, srcAddress, null, destAddress, bytes);} // Liberar memoria pública Native void Freememory (dirección larga); 2.6 Relacionado con el sistema
// Devuelve el tamaño del puntero. El valor de retorno es 4 u 8. Public Native Int DirectSize (); /** El valor de {@code direccionalSize ()}*/public static final int dirección_size = theUnsafe.addressSize (); // El tamaño de la página de memoria. Public Native Int PageSize ();3. Materiales de referencia
//www.vevb.com/article/140709.htm hablemos de la clase insegura en Java
//www.vevb.com/article/140721.htm Java Magic Class: Sun.misc.unsafe
Resumir
Lo anterior es todo el contenido de este artículo. Espero que el contenido de este artículo tenga cierto valor de referencia para el estudio o el trabajo de todos. Si tiene alguna pregunta, puede dejar un mensaje para comunicarse. Gracias por su apoyo a Wulin.com.