[ Web Proxy ]
URL:
Viewing: https://raw.githubusercontent.com/Coder994/JavaGuide/patch-1/docs/java/basis/unsafe.md [Back]  [Original]

---
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  ****

![](https://guide-blog-images.oss-cn-shenzhen.aliyuncs.com/github/javaguide/java/basis/unsafe/image-20220717115231125.png)

****

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



![](https://guide-blog-images.oss-cn-shenzhen.aliyuncs.com/github/javaguide/java/basis/unsafe/image-20220717144344005.png)

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

![](https://guide-blog-images.oss-cn-shenzhen.aliyuncs.com/github/javaguide/java/basis/unsafe/image-20220717144354582.png)

`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`

![](https://guide-blog-images.oss-cn-shenzhen.aliyuncs.com/github/javaguide/java/basis/unsafe/image-20220717144703446.png)

 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`

![](https://guide-blog-images.oss-cn-shenzhen.aliyuncs.com/github/javaguide/java/basis/unsafe/image-20220717144834132.png)

`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 

![](https://guide-blog-images.oss-cn-shenzhen.aliyuncs.com/github/javaguide/java/basis/unsafe/image-20220717144927257.png)

### 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`

![](https://guide-blog-images.oss-cn-shenzhen.aliyuncs.com/github/javaguide/java/basis/unsafe/image-20220717144950116.png)

### 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 

![](https://guide-blog-images.oss-cn-shenzhen.aliyuncs.com/github/javaguide/java/basis/unsafe/image-20220717145000710.png)

`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` 

Web Proxy Viewer  |  New URL  |  Original Page