【JAVA笔记——道】JAVA内存操作 sun.misc.Unsafe类

来源:互联网 发布:python urlencode 编辑:程序博客网 时间:2024/06/15 12:17

TIP:这是一个很危险的类,不熟悉情况下别用于生产环境

如果大家熟悉java concurrent,相信对Unsafe类不陌生。

我们知道JAVA作为高级语言的重要创新一点就是在于JVM的内存管理功能,这完全区别于C语言开发过程中需要对变量的内存分配小心控制,JVM很大程度解放了码农对于内存的调整。一直以来,JAVA在大多数人心目中没有办法对内存进行操作的,其实不然,Unsafe类就是一把操作JAVA内存的钥匙。

//不可以直接被初始化private Unsafe() {}//可以通过get获得实例public static Unsafe getUnsafe() {         Class<?> caller = Reflection.getCallerClass();          if (!VM.isSystemDomainLoader(caller.getClassLoader()))             throw new SecurityException("Unsafe");         return theUnsafe;     }

在这里需要注意isSystemDomainLoader,若不设置为static final将会导致SecurityException异常

这里简单介绍几个方法:

1 类值域初始化
推荐先看一下Class初始化理解
一般类实例化的方式主要有:1.new;2.Reflect;3.ClassLoader,不同方式对应不同初始化方式

    //Unsafe提供获取实例地址    public native Object allocateInstance(Class<?> cls)        throws InstantiationException;    //直接根据内存地址获取byte,Unsafe还提供了Int,Long等基本类型    //的线程安全及非线程安全取值    public native byte  getByte(long address);    //同样提供了对内存数据的直接修改,并提供基本类型的线程安全及非安全    //赋值    public native void  putByte(long address,byte x);

2 克隆
克隆之前经常用到两种方式:1.浅度克隆;2.深度克隆
浅度克隆实现的主要方式是clonable接口的clone方法以及通过反射获取clone对象。
深度克隆一般就比较麻烦了,需要自定义深度克隆方法。
现在我们可以操控内存,不论深度克隆亦或者浅度克隆,都只是对内存对象的操作,通过内存控制,我们很容易实现对象克隆。

//熟悉的内存分配public native long allocateMemory(long bytes);//熟悉的内存释放public native void freeMemory(long address);//内存复制,C的感觉回来了吧,浅度克隆一句搞定//深度克隆需要考虑克隆程度,因此推荐使用WakeObject,利用反射进行克隆public void copyMemory(long srcAddress, long destAddress, long bytes) {560         copyMemory(null, srcAddress, null, destAddress, bytes);561     }

3.懒加载
经常并发的数据结构中低级别的优化。

//常并发控制中,简称CAS(Compare And Swap),意思是如果valueOffset//位置包含的值与expect值相同,则更新valueOffset位置的值为update,//并返回true,否则不更新,返回falsepublic final native boolean compareAndSwapInt(Object o, long offset, int expected, int x);//懒加载public native void putOrderedInt(Object o, long offset, int x);

推荐看一下这篇,写的真心太好,觉得不需要再赘述JUC中Atomic class之lazySet的一点疑惑

Unsafe做操作的是直接内存区,所以该类没有办法通过HotSpot的GC进行回收,需要进行手动回收,因此在使用此类时需要注意内存泄漏(Memory Leak)和内存溢出(Out Of Memory)

0 0