publicfinalclassUnsafe { static { Reflection.registerMethodsToFilter(Unsafe.class, Set.of("getUnsafe")); } privateUnsafe() {} privatestaticfinalUnsafetheUnsafe=newUnsafe(); privatestaticfinal jdk.internal.misc.UnsafetheInternalUnsafe= jdk.internal.misc.Unsafe.getUnsafe(); /** * Provides the caller with the capability of performing unsafe * operations. * * <p>The returned {@code Unsafe} object should be carefully guarded * by the caller, since it can be used to read and write data at arbitrary * memory addresses. It must never be passed to untrusted code. * * <p>Most methods in this class are very low-level, and correspond to a * small number of hardware instructions (on typical machines). Compilers * are encouraged to optimize these methods accordingly. * * <p>Here is a suggested idiom for using unsafe operations: * * <pre> {@code * class MyTrustedClass { * private static final Unsafe unsafe = Unsafe.getUnsafe(); * ... * private long myCountAddress = ...; * public int getCount() { return unsafe.getByte(myCountAddress); } * }}</pre> * * (It may assist compilers to make the local variable {@code final}.) * * @throws SecurityException if the class loader of the caller * class is not in the system domain in which all permissions * are granted. */@CallerSensitive publicstatic Unsafe getUnsafe() { Class<?> caller = Reflection.getCallerClass(); if (!VM.isSystemDomainLoader(caller.getClassLoader())) thrownewSecurityException("Unsafe"); return theUnsafe; } ......
我们可以通过反射获取unsafe
1 2 3 4
Class<?> name = Class.forName("sun.misc.Unsafe"); FieldtheUnsafe= name.getDeclaredField("theUnsafe"); theUnsafe.setAccessible(true); Unsafeunsafe= (Unsafe) theUnsafe.get(null);
内存操作
这部分主要包含堆外内存的分配、拷贝、释放、给定地址值操作等方法。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
//分配内存, 相当于C++的malloc函数 publicnativelongallocateMemory(long bytes); //扩充内存 publicnativelongreallocateMemory(long address, long bytes); //释放内存 publicnativevoidfreeMemory(long address); //在给定的内存块中设置值 publicnativevoidsetMemory(Object o, long offset, long bytes, byte value); //内存拷贝 publicnativevoidcopyMemory(Object srcBase, long srcOffset, Object destBase, long destOffset, long bytes); //获取给定地址值,忽略修饰限定符的访问限制。与此类似操作还有: getInt,getDouble,getLong,getChar等 publicnative Object getObject(Object o, long offset); //为给定地址设置值,忽略修饰限定符的访问限制,与此类似操作还有: putInt,putDouble,putLong,putChar等 publicnativevoidputObject(Object o, long offset, Object x); //获取给定地址的byte类型的值(当且仅当该内存地址为allocateMemory分配时,此方法结果为确定的) publicnativebytegetByte(long address); //为给定地址设置byte类型的值(当且仅当该内存地址为allocateMemory分配时,此方法结果才是确定的) publicnativevoidputByte(long address, byte x);
//返回对象成员属性在内存地址相对于此对象的内存地址的偏移量 publicnativelongobjectFieldOffset(Field f); //获得给定对象的指定地址偏移量的值,与此类似操作还有:getInt,getDouble,getLong,getChar等 publicnative Object getObject(Object o, long offset); //给定对象的指定地址偏移量设值,与此类似操作还有:putInt,putDouble,putLong,putChar等 publicnativevoidputObject(Object o, long offset, Object x); //从对象的指定偏移量处获取变量的引用,使用volatile的加载语义 publicnative Object getObjectVolatile(Object o, long offset); //存储变量的引用到对象的指定的偏移量处,使用volatile的存储语义 publicnativevoidputObjectVolatile(Object o, long offset, Object x); //有序、延迟版本的putObjectVolatile方法,不保证值的改变被其他线程立即看到。只有在field被volatile修饰符修饰时有效 publicnativevoidputOrderedObject(Object o, long offset, Object x); //绕过构造方法、初始化代码来创建对象 publicnative Object allocateInstance(Class<?> cls)throws InstantiationException;