Unsafe可用来直接访问系统内存资源并自主管理,在提升Java运行效率、增强Java语言底层操作能力方面起了很大的作用——可以认为,Unsafe类是Java中留下的后门,提供了一些低层次操作,如直接内存访问、线程调度等。
Unsafe不属于Java标准。官方并不建议使用Unsafe,并且从JDK 9开始,官方开始去Unsafe! 相关Issue:https://bugs.java.com/bugdatabase/view_bug.do?bug_id=6852936
因此,Unsafe类对于项目实战,意义并不大。然而目前业界有很多好用的类库大量使用了Unsafe类,例如 java.util.concurrent.atomic 包里的一堆类、Netty、Hadoop、Kafka等。所以了解一下还是有好处的。
不同的JDK版本中,Unsafe类也有区别,例如:

  • 在JDK 8中归属于sun.misc包下;
  • 在JDK 11中归属于sun.misc包或jdk.internal.misc下,其中jdk.internal.misc下的Unsafe类功能更强。(应该是从JDK 9开始的,笔者未亲测)

    快速上手

    ```java import sun.misc.Unsafe; import java.lang.reflect.Field;

public class DirectMemoryTest1 { private static final int _1MB = 1024 * 1024;

  1. public static void main(String[] args) throws IllegalAccessException {
  2. //通过反射获取Unsafe类并通过其分配直接内存
  3. Field unsafeField = Unsafe.class.getDeclaredFields()[0];
  4. unsafeField.setAccessible(true);
  5. Unsafe unsafe = (Unsafe) unsafeField.get(null);
  6. int i = 0;
  7. while (true) {
  8. unsafe.allocateMemory(_1MB);
  9. System.out.println(++i);
  10. }
  11. }

}

  1. <a name="yRXaj"></a>
  2. ## Unsafe类的使用
  3. 详见:
  4. - [https://www.jb51.net/article/140726.htm](https://www.jb51.net/article/140726.htm)
  5. - [https://blog.csdn.net/ahilll/article/details/81628215](https://blog.csdn.net/ahilll/article/details/81628215)
  6. - [https://www.jianshu.com/p/dd2be4d3b88e](https://www.jianshu.com/p/dd2be4d3b88e)
  7. <a name="KfdjW"></a>
  8. ## JDK 11如何使用Unsafe类
  9. > **TIPS**
  10. > 再次强调,实际项目中,除非情非得已,尽量不要用Unsafe类,官方不建议使用
  11. > 从JDK 10开始,Unsafe类的部分功能已经被VarHandle取代,建议用VarHandle
  12. - 创建一个JDK 11的项目
  13. - 在项目源码路径下创建module-info.java ,内容如下:
  14. ```java
  15. module unsafe {
  16. requires jdk.unsupported;
  17. }

创建后,代码结构如下:|

  1. |____src
  2. | |____main
  3. | | |____java
  4. | | | |____module-info.java
  5. | | | |____com
  6. | | | | |____example
  7. | | | | | |____demo
  8. | | | | | | |____UnsafePlayer.java
  9. | | | | | | |____DirectMemoryTest1.java
  • 测试代码: ```java import sun.misc.Unsafe; import java.lang.reflect.Field;

public class DirectMemoryTest1 { private static final int _1MB = 1024 * 1024;

  1. public static void main(String[] args) throws IllegalAccessException {
  2. //通过反射获取Unsafe类并通过其分配直接内存
  3. Field unsafeField = Unsafe.class.getDeclaredFields()[0];
  4. unsafeField.setAccessible(true);
  5. Unsafe unsafe = (Unsafe) unsafeField.get(null);
  6. int i = 0;
  7. while (true) {
  8. unsafe.allocateMemory(_1MB);
  9. System.out.println(++i);
  10. }

} } ```

参考文档