Preface
This article mainly introduces relevant content about the Unsafe class in Java. It is shared for your reference and learning. I won’t say much below. Let’s take a look at the detailed introduction together.
1. Unsafe class introduction
The Unsafe class is under the sun.misc package and does not belong to the Java standard. However, many Java basic class libraries, including some widely used high-performance development libraries, are developed based on Unsafe class, such as Netty, Hadoop, Kafka, etc.
Unsafe can be used to directly access system memory resources and manage independently. The Unsafe class plays a great role in improving Java operation efficiency and enhancing the underlying operation capabilities of the Java language.
Unsafe can be considered a backdoor left in Java, providing some low-level operations, such as direct memory access, thread scheduling, etc.
Unsafe is not recommended.
Here are some examples of using Unsafe.
1.1 Instantiate a private class
import java.lang.reflect.Field; import sun.misc.Unsafe; public class UnsafePlayer { public static void main(String[] args) throws Exception { //Instantiate Unsafe Field f = Unsafe.class.getDeclaredField("theUnsafe"); f.setAccessible(true); Unsafe unsafe = (Unsafe) f.get(null); //Instantiate Player Player player = (Player) unsafe.allocateInstance(Player.class); player.setName("li lei"); System.out.println(player.getName()); } } class Player{ private String name; private Player(){} public String getName() { return name; } public void setName(String name) { this.name = name; } } 1.2CAS operation, change the value of the meter through memory offset address modification
Use CAS to update the top of the stack in TransferStack in SynchronousQueue in Java concurrency package.
/ Unsafe mechanicsprivate static final sun.misc.Unsafe UNSAFE;private static final long headOffset;static { try { UNSAFE = sun.misc.Unsafe.getUnsafe(); Class<?> k = TransferStack.class; headOffset = UNSAFE.objectFieldOffset (k.getDeclaredField("head")); } catch (Exception e) { throw new Error(e); }}//Volatile SNode head;//Update the top of the stack boolean casHead(SNode h, SNode nh) { return h == head && UNSAFE.compareAndSwapObject(this, headOffset, h, nh);} 1.3 Direct memory access
Unsafe's direct memory access: The memory space opened with Unsafe does not occupy Heap space, and of course it does not have automatic memory recovery function. Make it possible to use system memory resources freely like C.
2. Unsafe class source code analysis
Most of Unsafe's APIs are native methods, mainly including the following categories:
1) Class related. Mainly provides Class and its static fields operation methods.
2) Object related. Mainly provides the operation methods of Object and its fields.
3) Arrray related. Mainly provides the operation methods of arrays and elements in them.
4) Concurrent correlation. It mainly provides low-level synchronization primitives, such as CAS, thread scheduling, volatile, memory barrier, etc.
5) Memory related. It provides a direct memory access method (bypassing the Java heap and directly manipulating local memory), which can freely utilize system memory resources like C.
6) System related. It mainly returns some low-level memory information, such as address size and memory page size.
2.1Class related
//The offset of static attributes is used to read and write static attributes in the corresponding Class object public native long staticFieldOffset(Field f); public native Object staticFieldBase(Field f);//Judge whether a class needs to be initialized public native boolean shouldBeInitialized(Class<?> c);//Ensure that the class is initialized public native void ensureClassInitialized(Class<?> c);//Define a class that can be used to dynamically create classes public native Class<?> defineClass(String name, byte[] b, int off, int len, ClassLoader loader, ProtectionDomain protectionDomain);//Define an anonymous class that can be used to dynamically create classes public native Class<?> defineAnonymousClass(Class<?> hostClass, byte[] data, Object[] cpPatches);
2.2Object-related
There are the following methods for basic types (boolean, byte, char, short, int, long, float, double) and object reference types in Java.
//Get the field offset of the object public native long objectFieldOffset(Field f); //Get the int value of the given object address offset public native int getInt(Object o, long offset); //Set the int value of the given object address offset public native void putInt(Object o, long offset, int x);
//Create an object, but its constructor will not be called. If the class is not initialized, the class is initialized. public native Object allocateInstance(Class<?> cls) throws InstantiationException;
2.3 Array Related
/** * Report the offset of the first element in the storage allocation of a * given array class. If {@link #arrayIndexScale} returns a non-zero value * for the same class, you may use that scale factor, together with this * base offset, to form new offsets to access elements of arrays of the * given class. * * @see #getInt(Object, long, int) *///Return the offset address of the first element in the array public native int arrayBaseOffset(Class<?> arrayClass);//boolean, byte, short, char, int, long, float, double, and object types have the following methods/** The value of {@code arrayBaseOffset(boolean[].class)} */public static final int ARRAY_BOOLEAN_BASE_OFFSET = theUnsafe.arrayBaseOffset(boolean[].class); /** * Report the scale factor for addressing elements in the storage * allocation of a given array class. However, arrays of "narrow" types * will generally not work properly with accessors like {@link * #getByte(Object, int)}, so the scale factor for such classes is reported * as zero. * * @see #arrayBaseOffset * @see #getInt(Object, long) * @see #putInt(Object, long, int) *///Return the size occupied by each element in the array public native int arrayIndexScale(Class<?> arrayClass); //boolean, byte, short, char, int, long, float, double, and object types have the following methods/** The value of {@code arrayIndexScale(boolean[].class)} */public static final int ARRAY_BOOLEAN_INDEX_SCALE = theUnsafe.arrayIndexScale(boolean[].class); The location of each element in the array in memory can be located through arrayBaseOffset and arrayIndexScale.
2.4 Concurrency Related
2.4.1CAS related
CAS: CompareAndSwap, memory offset address offset, expected value expected, new value x. If the value of the variable at the current time and the expected value are equal, try to update the value of the variable to x. Return true if the update is successful; otherwise, return false.
//Update the variable value to x, if the current value is expected//o: Object offset: Offset expected: Expected value x: New value public final native boolean compareAndSwapObject(Object o, long offset, Object expected, Object x); public final native boolean compareAndSwapInt(Object o, long offset, int expected, int x); public final native boolean compareAndSwapLong(Object o, long offset, long expected, long x);
Starting with Java 8, the following methods are provided in Unsafe:
//Add public final int getAndAddInt(Object o, long offset, int delta) { int v; do { v = getIntVolatile(o, offset); } while (!compareAndSwapInt(o, offset, v, v + delta)); return v;} public final long getAndAddLong(Object o, long offset, long delta) { long v; do { v = getLongVolatile(o, offset); } while (!compareAndSwapLong(o, offset, v, v + delta)); return v;}//Set public final int getAndSetInt(Object o, long offset, int newValue) { int v; do { v = getIntValatile(o, offset); } while (!compareAndSwapInt(o, offset, v, newValue)); return v;} public final long getAndSetLong(Object o, long offset, long newValue) { long v; do { v = getLongValatile(o, offset); } while (!compareAndSwapLong(o, offset, v, newValue)); return v;} public final Object getAndSetObject(Object o, long offset, Object newValue) { Object v; do { v = getObjectValatile(o, offset); } while (!compareAndSwapObject(o, offset, v, newValue)); return v;2.4.2 Thread scheduling related
//Unblocking thread public native void unpark(Object thread);//Blocking thread public native void park(boolean isAbsolute, long time);//Get object lock public native void monitorEnter(Object o);//Release object lock public native void monitorExit(Object o);//Try to obtain object lock, return true or false to indicate whether it is successful public native boolean tryMonitorEnter(Object o);
2.4.3 volatile related reading and writing
There are the following methods for basic types (boolean, byte, char, short, int, long, float, double) and object reference types in Java.
//Get the reference of the variable from the specified offset of the object, and use the load semantics of volatile //Equivalent to the volatile version of getObject(Object, long) public native Object getObjectVolatile(Object o, long offset); //Storage the reference of the variable to the specified offset of the object, and use the storage semantics of volatile //Equivalent to the volatile version of putObject(Object, long, Object) public native void putObjectVolatile(Object o, long offset, Object x);
/** * Version of {@link #putObjectVolatile(Object, long, Object)} * that does not guarantee immediate visibility of the store to * other threads. This method is generally only useful if the * underlying field is a Java volatile (or if an array cell, one * that is otherwise only accessed using volatile accesses). */public native void putOrderedObject(Object o, long offset, Object x); /** Ordered/Lazy version of {@link #putIntVolatile(Object, long, int)} */public native void putOrderedInt(Object o, long offset, int x); /** Ordered/Lazy version of {@link #putLongVolatile(Object, long, long)} */public native void putOrderedLong(Object o, long offset, long x);2.4.4 Memory barrier related
Java 8 was introduced to define memory barriers to avoid code reordering.
//Memory barrier, prohibits load operations from being reordered, that is, load operations before the barrier cannot be reordered to the barrier, load operations after the barrier cannot be reordered to the front of the barrier public native void loadFence();//Memory barrier, prohibits store operations before the barrier, prohibits store operations after the barrier, public native void storeFence();//Memory barrier, prohibits load and store operations from being reordered to the front of the barrier public native void fullFence();
2.5 Direct memory access (non-heap memory)
The memory allocated by allocateMemory needs to be manually free (not recycled by GC)
//(boolean, byte, char, short, int, long, float, double) have the following two methods: get and put. //Get the int value at the given address public native int getInt(long address);//Set the int value at the given address public native void putInt(long address, int x);//Get local pointer public native long getAddress(long address);//Storage the local pointer to the given memory address public native void putAddress(long address, long x); //Allocate memory public native long allocateMemory(long bytes);//Reallocate memory public native long reallocateMemory(long address, long bytes);//Initialize the memory content public native void setMemory(Object o, long offset, long bytes, byte value);//Initialize the memory content public void setMemory(long address, long bytes, byte value) { setMemory(null, 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);}//Release memory public native void freeMemory(long address); 2.6 System Related
//Return the size of the pointer. The return value is 4 or 8. public native int addressSize(); /** The value of {@code addressSize()} */public static final int ADDRESS_SIZE = theUnsafe.addressSize(); //The size of the memory page. public native int pageSize();3. Reference materials
//www.VeVB.COM/article/140709.htm Let's talk about the Unsafe class in Java
//www.VeVB.COM/article/140721.htm java magic class: sun.misc.Unsafe
Summarize
The above is the entire content of this article. I hope that the content of this article has certain reference value for everyone's study or work. If you have any questions, you can leave a message to communicate. Thank you for your support to Wulin.com.