---
title: Java Unsafe
category: Java
tag:
- Java
---
>
>
> - [JavaUnsafe - -2019](https://tech.meituan.com/2019/02/14/talk-about-java-magic-class-unsafe.html)
> - [Java Unsafe - - 2021](https://xie.infoq.cn/article/8b6ed4195e475bfb32dacc5cb)
JUC `Unsafe`
## Unsafe
`Unsafe` `sun.misc` Java Java `Unsafe` Java C `Unsafe` Java `Unsafe`
`Unsafe` Native Method Java **`native`** Java ****

****
1. Java Java
2. Java
3. C/C++
JUC Java
## Unsafe
`sun.misc.Unsafe`
```java
public final class Unsafe {
//
private static final Unsafe theUnsafe;
......
private Unsafe() {
}
@CallerSensitive
public static Unsafe getUnsafe() {
Class var0 = Reflection.getCallerClass();
// `BootstrapClassLoader`
if(!VM.isSystemDomainLoader(var0.getClassLoader())) {
throw new SecurityException("Unsafe");
} else {
return theUnsafe;
}
}
}
```
`Unsafe` `getUnsafe` `Unsafe` `Unsafe` `SecurityException`
```bash
Exception in thread "main" java.lang.SecurityException: Unsafe
at sun.misc.Unsafe.getUnsafe(Unsafe.java:90)
at com.cn.test.GetUnsafeTest.main(GetUnsafeTest.java:12)
```
** `public static` **
`getUnsafe``classLoader``Bootstrap classLoader``SecurityException` Unsafe
** Unsafe ?**
`Unsafe`
** `Unsafe` **
1 Unsafe `theUnsafe`
```java
private static Unsafe reflectGetUnsafe() {
try {
Field field = Unsafe.class.getDeclaredField("theUnsafe");
field.setAccessible(true);
return (Unsafe) field.get(null);
} catch (Exception e) {
log.error(e.getMessage(), e);
return null;
}
}
```
2`getUnsafe` Java `-Xbootclasspath/a` Unsafe A jar bootstrap A `Unsafe.getUnsafe` Unsafe
```bash
java -Xbootclasspath/a: ${path} // pathUnsafejar
```
## Unsafe
`Unsafe` 8
1.
2.
3.
4.
5. CAS
6.
7. Class
8.
###
####
C C++ Java JVM `Unsafe`
```java
//
public native long allocateMemory(long bytes);
//
public native long reallocateMemory(long address, long bytes);
//
public native void setMemory(Object o, long offset, long bytes, byte value);
//
public native void copyMemory(Object srcBase, long srcOffset,Object destBase, long destOffset,long bytes);
//
public native void freeMemory(long address);
```
```java
private void memoryTest() {
int size = 4;
long addr = unsafe.allocateMemory(size);
long addr3 = unsafe.reallocateMemory(addr, size * 2);
System.out.println("addr: "+addr);
System.out.println("addr3: "+addr3);
try {
unsafe.setMemory(null,addr ,size,(byte)1);
for (int i = 0; i < 2; i++) {
unsafe.copyMemory(null,addr,null,addr3+size*i,4);
}
System.out.println(unsafe.getInt(addr));
System.out.println(unsafe.getLong(addr3));
}finally {
unsafe.freeMemory(addr);
unsafe.freeMemory(addr3);
}
}
```
```
addr: 2433733895744
addr3: 2433733894944
16843009
72340172838076673
```
`allocateMemory` 4 `setMemory``byte` 1 Unsafe `getInt``int` 4 4 `int` 16843009

`reallocateMemory` 8 `addr``addr3` for `copyMemory``addr` 4 `addr3``addr3+4`

`getLong` 8 `long` 72340172838076673
`freeMemory``try``finally`
****
- JVM GC
- I/O I/O
####
`DirectByteBuffer` Java NettyMINA NIO `DirectByteBuffer` Unsafe API
`DirectByteBuffer` `DirectByteBuffer` `Unsafe.allocateMemory` `Unsafe.setMemory` `Cleaner` `DirectByteBuffer` `DirectByteBuffer`
```java
DirectByteBuffer(int cap) { // package-private
super(-1, 0, cap, cap);
boolean pa = VM.isDirectMemoryPageAligned();
int ps = Bits.pageSize();
long size = Math.max(1L, (long)cap + (pa ? ps : 0));
Bits.reserveMemory(size, cap);
long base = 0;
try {
//
base = unsafe.allocateMemory(size);
} catch (OutOfMemoryError x) {
Bits.unreserveMemory(size, cap);
throw x;
}
//
unsafe.setMemory(base, size, (byte) 0);
if (pa && (base % ps != 0)) {
// Round up to page boundary
address = base + ps - (base & (ps - 1));
} else {
address = base;
}
// DirectByteBuffer
cleaner = Cleaner.create(this, new Deallocator(base, size, cap));
att = null;
}
```
###
####
CPU CPU `Memory Barrier`
CPU Java8 3 JVM
`Unsafe`
```java
//loadloadload
public native void loadFence();
//storestorestore
public native void storeFence();
//loadstore
public native void fullFence();
```
`loadFence`
`volatile``volatile``flag``flag``volatile`
```java
@Getter
class ChangeThread implements Runnable{
/**volatile**/ boolean flag=false;
@Override
public void run() {
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("subThread change flag to:" + flag);
flag = true;
}
}
```
`while``flag`
```java
public static void main(String[] args){
ChangeThread changeThread = new ChangeThread();
new Thread(changeThread).start();
while (true) {
boolean flag = changeThread.isFlag();
unsafe.loadFence(); //
if (flag){
System.out.println("detected flag changed");
break;
}
}
System.out.println("main thread end");
}
```
```
subThread change flag to:false
detected flag changed
main thread end
```
`loadFence``flag``while`

Java `JMM`
####
Java 8 `StampedLock``StampedLock` `StampedLock` load
`StampedLock` `validate` `Unsafe` `loadFence` `load`
```java
public boolean validate(long stamp) {
U.loadFence();
return (stamp & SBITS) == (state & SBITS);
}
```
###
####
****
`putInt``getInt`Unsafe 8 `Object``put``get``put` openJDK `Object``value``Object``reference value``Object`
```java
//
public native Object getObject(Object o, long offset);
//
public native void putObject(Object o, long offset, Object x);
```
`Unsafe` **volatile ******`volatile``Object``int`
```java
//intvolatile load
public native int getIntVolatile(Object o, long offset);
//intvolatile store
public native void putIntVolatile(Object o, long offset, int x);
```
`volatile``get``put`
```java
public native void putOrderedObject(Object o, long offset, Object x);
public native void putOrderedInt(Object o, long offset, int x);
public native void putOrderedLong(Object o, long offset, long x);
```
`volatile`
- `Load`
- `Store`
`volatile``StoreStore``volatile``StoreLoad`

`StoreStore``Store1``Store2``volatile``StoreLoad``Store1``Load2``StoreLoad`
`put``putOrder``putVolatile`
****
`Unsafe` `allocateInstance`
```java
@Data
public class A {
private int b;
public A(){
this.b =1;
}
}
```
`Unsafe`
```java
public void objTest() throws Exception{
A a1=new A();
System.out.println(a1.getB());
A a2 = A.class.newInstance();
System.out.println(a2.getB());
A a3= (A) unsafe.allocateInstance(A.class);
System.out.println(a3.getB());
}
```
110`allocateInstance``Class` A `private``allocateInstance`
####
- **** new new
- **** Unsafe allocateInstance Class JVM private allocateInstance java.lang.invokeObjenesisGson
###
####
`arrayBaseOffset` `arrayIndexScale`
```java
//
public native int arrayBaseOffset(Class arrayClass);
//
public native int arrayIndexScale(Class arrayClass);
```
####
`java.util.concurrent.atomic` `AtomicIntegerArray` `Integer` `AtomicIntegerArray` `Unsafe` `arrayBaseOffset` `arrayIndexScale` `base` `scale` `getAndAdd` `checkedByteOffset` CAS

### CAS
####
CAS
```java
/**
* CAS
* @param o field
* @param offset field
* @param expected
* @param update
* @return true | false
*/
public final native boolean compareAndSwapObject(Object o, long offset, Object expected, Object update);
public final native boolean compareAndSwapInt(Object o, long offset, int expected,int update);
public final native boolean compareAndSwapLong(Object o, long offset, long expected, long update);
```
** CAS?** CAS Compare And Swap)CAS CAS CAS CPU cmpxchg `Unsafe` CAS `compareAndSwapXXX` CPU `cmpxchg`
####
JUC CAS `synchronized``AQS` CAS `Unsafe` `compareAndSwapObject``compareAndSwapInt``compareAndSwapLong``Object``int``long` CAS `compareAndSwapInt`
```java
public final native boolean compareAndSwapInt(Object o, long offset,int expected,int x);
```
`o``offset``o``expected``x``compareAndSwapInt`
```java
private volatile int a;
public static void main(String[] args){
CasTest casTest=new CasTest();
new Thread(()->{
for (int i = 1; i < 5; i++) {
casTest.increment(i);
System.out.print(casTest.a+" ");
}
}).start();
new Thread(()->{
for (int i = 5 ; i {
try {
TimeUnit.SECONDS.sleep(5);
System.out.println("subThread try to unpark mainThread");
unsafe.unpark(mainThread);
} catch (InterruptedException e) {
e.printStackTrace();
}
}).start();
System.out.println("park main mainThread");
unsafe.park(false,0L);
System.out.println("unpark mainThread success");
}
```
```
park main mainThread
subThread try to unpark mainThread
unpark mainThread success
```
`park` 5 `unpark`

### Class
####
`Unsafe` `Class`
****
```java
//
public native long staticFieldOffset(Field f);
//
public native Object staticFieldBase(Field f);
//
public native boolean shouldBeInitialized(Class c);
```
```java
@Data
public class User {
public static String name="Hydra";
int age;
}
private void staticTest() throws Exception {
User user=new User();
System.out.println(unsafe.shouldBeInitialized(User.class));
Field sexField = User.class.getDeclaredField("name");
long fieldOffset = unsafe.staticFieldOffset(sexField);
Object fieldBase = unsafe.staticFieldBase(sexField);
Object object = unsafe.getObject(fieldBase, fieldOffset);
System.out.println(object);
}
```
```
falseHydra
```
`Unsafe` `objectFieldOffset``staticFieldOffset``Field``Class``Class`
`User``null``shouldBeInitialized` User
```
truenull
```
**`defineClass`**
```java
public native Class defineClass(String name, byte[] b, int off, int len, ClassLoader loader,ProtectionDomain protectionDomain);
```
`ClassLoader``ProtectionDomain` class
```java
private static void defineTest() {
String fileName="F:\\workspace\\unsafe-test\\target\\classes\\com\\cn\\model\\User.class";
File file = new File(fileName);
try(FileInputStream fis = new FileInputStream(file)) {
byte[] content=new byte[(int)file.length()];
fis.read(content);
Class clazz = unsafe.defineClass(null, content, 0, content.length, null, null);
Object o = clazz.newInstance();
Object age = clazz.getMethod("getAge").invoke(o, null);
System.out.println(age);
} catch (Exception e) {
e.printStackTrace();
}
}
```
`class``defineClass` JVM

`defineClass`Unsafe `defineAnonymousClass`
```java
public native Class defineAnonymousClass(Class hostClass, byte[] data, Object[] cpPatches);
```
`Lambda` ASM JDK 15 `Hidden classes` `Unsafe` `defineAnonymousClass`
####
Lambda `Unsafe` `defineAnonymousClass`
###
####
```java
//432 864
public native int addressSize();
//2
public native int pageSize();
```
####
`java.nio.Bits``pageCount``pageSize``copySwapMemory``addressSize` 32
##
`Unsafe` API `Unsafe` Java9 `Unsafe` Java16 `Unsafe`