博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Java魔法师Unsafe
阅读量:4040 次
发布时间:2019-05-24

本文共 2298 字,大约阅读时间需要 7 分钟。

Unsafe是位于sun.misc包下的一个类,主要提供一些用于执行低级别、不安全操作的方法,如直接访问系统内存资源、自主管理内存资源等,这些方法在提升Java运行效率、增强Java语言底层资源操作能力方面起到了很大的作用。

Unsafe的单例实现:

@CallerSensitive    public static Unsafe getUnsafe() {        Class var0 = Reflection.getCallerClass();        if (!VM.isSystemDomainLoader(var0.getClassLoader())) {            throw new SecurityException("Unsafe");        } else {            return theUnsafe;        }    }

当且仅当调用getUnsafe方法的类为引导类加载器所加载时才合法,否则抛出SecurityException异常。

可以通过反射的方式获得theUnsafe。

try {            Field f = Unsafe.class.getDeclaredField("theUnsafe");            // 将字段的访问权限设置为true            f.setAccessible(true);            // 因为theUnsafe字段在Unsafe类中是一个静态字段,所以通过Field.get()获取字段值时,可以传null获取            Unsafe unsafe = (Unsafe) f.get(null);            Author author = (Author) unsafe.allocateInstance(Author.class) ;            Field ageField = Author.class.getDeclaredField("age") ;            long fieldOffset = unsafe.objectFieldOffset(ageField) ;            String[] strings = new String[]{"1","2","3"} ;            // 返回数组中第一个元素在内存中的偏移量            long i = unsafe.arrayBaseOffset(String[].class) ;            long address = unsafe.allocateMemory(8L) ;            log.info("address:"+address);        }catch (NoSuchFieldException e) {            e.printStackTrace();        } catch (IllegalAccessException e) {            e.printStackTrace();        }catch (InstantiationException e) {            e.printStackTrace();        }

Unsafe主要提供的功能如下:

  • 内存操作

典型应用:DirectByteBuffe,提供堆外内存的缓冲池,为NIO框架广泛使用。

  • CAS操作

典型应用java.util.concurrent.atomic相关类,保证原子操作,支持多线程并发

  • 线程操作

Java锁和同步器框架的核心类AbstractQueuedSynchronizer,就是通过调用LockSupport.park()和LockSupport.unpark()实现线程的阻塞和唤醒的

  • class类操作

从Java 8开始,JDK使用invokedynamic及VM Anonymous Class结合来实现Java语言层面上的Lambda表达式。

  • 对象操作

Unsafe中提供allocateInstance方法,仅通过Class对象就可以创建此类的实例对象,而且不需要调用其构造函数、初始化代码、JVM安全检查等。在Gson反序列化时,如果类有默认构造函数,则通过反射调用默认构造函数创建实例,否则通过UnsafeAllocator来实现对象实例的构造

  • 数组操作

java.util.concurrent.atomic 包下的AtomicIntegerArray(可以实现对Integer数组中每个元素的原子性操作)中有典型的应用,如下图AtomicIntegerArray源码所示,通过Unsafe的arrayBaseOffset、arrayIndexScale分别获取数组首元素的偏移地址base及单个元素大小因子scale。

  • 内存屏障

在Java 8中引入了一种锁的新机制——StampedLock,它可以看成是读写锁的一个改进版本。StampedLock提供了一种乐观读锁的实现

  • 系统相关

如下图所示的代码片段,为java.nio下的工具类Bits中计算待申请内存所需内存页数量的静态方法,其依赖于Unsafe中pageSize方法获取系统内存页大小实现后续计算逻辑。

 

更多更详细的说明以及典型使用查看美团技术写的

更多unsafe的API说明可以参考:

转载地址:http://axadi.baihongyu.com/

你可能感兴趣的文章
[LeetCode By Python]125. Valid Palindrome
查看>>
[LeetCode By Python]136. Single Number
查看>>
[LeetCode By MYSQL] Combine Two Tables
查看>>
Android下调用收发短信邮件等(转载)
查看>>
Android中电池信息(Battery information)的取得
查看>>
SVN客户端命令详解
查看>>
Android/Linux 内存监视
查看>>
Linux系统信息查看
查看>>
用find命令查找最近修改过的文件
查看>>
Android2.1消息应用(Messaging)源码学习笔记
查看>>
Android之TelephonyManager类的方法详解
查看>>
android raw读取超过1M文件的方法
查看>>
ubuntu下SVN服务器安装配置
查看>>
MPMoviePlayerViewController和MPMoviePlayerController的使用
查看>>
CocoaPods实践之制作篇
查看>>
[Mac]Mac 操作系统 常见技巧
查看>>
苹果Swift编程语言入门教程【中文版】
查看>>
捕鱼忍者(ninja fishing)之游戏指南+游戏攻略+游戏体验
查看>>
iphone开发基础之objective-c学习
查看>>
iphone开发之SDK研究(待续)
查看>>