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


    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,否则不更新,返回false
    public 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)

  • 相关阅读:
    HDU1069:Monkey and Banana(DP+贪心)
    hdu 4497 GCD and LCM(2013 ACM-ICPC吉林通化全国邀请赛——题目重现)
    vb6.0 倒计时
    硬盘分区表
    踽踽独行的岁月,感谢与你的相遇
    每天学点Linux:二
    windows下Qt Creator5.1.0编写程序以及调用OpenCV库
    【每周一译】愚蠢的指标:Java中使用最多的关键字
    centos 7 没有ifconfig 命令
    About stats collected
  • 原文地址:https://www.cnblogs.com/cunchen/p/9464171.html
Copyright © 2020-2023  润新知