Unsafe类在jdk 源码的多个类中用到,这个类的提供了一些绕开JVM的更底层功能,基于它的实现可以提高效率。但是,它是一把双刃剑:正如它的名字所预示的那样,它是 Unsafe的,它所分配的内存需要手动free(不被GC回收)。Unsafe类,提供了JNI某些功能的简单替代:确保高效性的同时,使事情变得更简 单。
这篇文章主要是以下文章的整理、翻译。
http://mishadoff.com/blog/java-magic-part-4-sun-dot-misc-dot-unsafe/
1. Unsafe API的大部分方法都是native实现,它由105个方法组成,主要包括以下几类:
(1)Info相关。主要返回某些低级别的内存信息:addressSize(), pageSize()
(2)Objects相关。主要提供Object和它的域操纵方法:allocateInstance(),objectFieldOffset()
(3)Class相关。主要提供Class和它的静态域操纵方法:staticFieldOffset(),defineClass(),defineAnonymousClass(),ensureClassInitialized()
(4)Arrays相关。数组操纵方法:arrayBaseOffset(),arrayIndexScale()
(5)Synchronization相关。主要提供低级别同步原语(如基于CPU的CAS(Compare-And-Swap)原 语):monitorEnter(),tryMonitorEnter(),monitorExit(),compareAndSwapInt(),putOrderedInt()
(6)Memory相关。直接内存访问方法(绕过JVM堆直接操纵本地内存):allocateMemory(),copyMemory(),freeMemory(),getAddress(),getInt(),putInt()
1 package com.yeepay.sxf.hashmaptest; 2 3 import java.lang.reflect.Field; 4 5 import sun.misc.Unsafe; 6 7 public class TestUnSafe { 8 9 public static void main(String[] args) throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException, InstantiationException { 10 //获取属性 11 Field f=Unsafe.class.getDeclaredField("theUnsafe"); 12 // 13 f.setAccessible(true); 14 //获取实例 15 Unsafe unsafe=(Unsafe) f.get(null); 16 17 //实例化一个类 18 Player player=(Player) unsafe.allocateInstance(Player.class); 19 //打印年龄 打印结果:0 20 System.out.println("TestUnSafe.enclosing_method()"+player.getAge()); 21 22 player.setAge(100); 23 24 //打印结果100 25 System.out.println("TestUnSafe.main()"+player.getAge()); 26 27 } 28 29 } 30 31 /** 32 * 普通类 33 * @author sxf 34 * 35 */ 36 class Player{ 37 //年龄 38 private int age=12; 39 40 //构造函数私有化 41 private Player(){ 42 this.age=50; 43 } 44 45 public int getAge() { 46 return age; 47 } 48 49 public void setAge(int age) { 50 this.age = age; 51 } 52 }