java中的5种引用

java中的5种引用
    强引用         不会回收
        指创建一个对象并把这个对象赋给一个引用变量。
        被GCRoot对象引用的对象是强引用对象
        
        当强引用有引用变量指向时不会被垃圾回收,抛出OutOfMemory错误也不会回收这种对象。

        如果想中断强引用和某个对象之间的关联,可以显示地将引用赋值为null


        GCRoot对象有以下几种类型:

            虚拟机栈(栈帧中的本地变量表)中引用的对象。
                即当前正被调用的方法的局部变量或参数,在方法执行期间保持活跃。

            方法区中类静态属性引用的对象。
                由系统类加载器或引导类加载器加载的类的静态字段,
                在类加载期间初始化,并且在类卸载之前一直存在。

            方法区中常量引用的对象。
                由final修饰的常量值,在编译期就已经确定,且在运行期不会改变。

            本地方法栈中JNI引用的对象。
                由Java调用非Java语言(如C或C++)实现的本地方法时产生的,
                可以通过本地方法接口(JNI)访问虚拟机内部数据或操作系统资源。
    

    软引用         一次gc后,内存任然不足,即回收软引用对象

        被SoftReference对象所引用的对象称为软引用对象,
        SoftReference对象调用get方法就会获取到它所软引用的那个对象。
         
        软引用 用来描述一些有用但非必须的对象, 当JVM进行垃圾回收时内存空间足够,
        垃圾回收器就不会回收软引用对象;但是当内存不够时会对软引用对象进行回收。

        软引用可用来实现内存敏感的高速缓存,比如网页缓存、图片缓存等。

        当然,当内存被gc后,就无法get访问到了

        也有些软引用数据,可以实时清理,就可以配合引用队列来清理,(先进先出)

        例:    
        List<SoftReference<byte[]>> list=new ArrayList<>();
        创建引用队列
        ReferenceQueue<byte[]> queue=new ReferenceQueue<>{};
        //关联软引用和引用队列
SoftRefef=rence<byte[]> ref=new softReference<>(new SoftReference<>(new byte[_1MB],queue));
        list.add(ref);
        //提取并清除无用软引用对象
        while(queue.poll()!=null){
            list.remove(queue.poll());
        }

    弱引用         发现即回收

        只被WeakReference对象引用的对象称为弱引用对象,弱引用也是用来描述非必须对象的,

        当gc垃圾回收时,无论内存是否充足,都会回收被弱引用关联的对象。
        一个对象被弱引用和这个对象没有引用的 gc垃圾回收 效果是一样的。

        它和完全没有引用的区别是,在垃圾回收之前可以通过get访问到它。 

        弱引用在threadlocal中有实际应用场景
    
        同样代码中也可以结合弱引用

        
        典型应用场景:
            缓存可以提高程序的性能和效率,但也会占用内存空间。
            弱引用来存一些不重要但是常用的数据

    引用队列ReferenceQueue:        虚引用和终结器引用要配合引用队列来使用


    虚引用         发现即回收        对象回收跟踪(清理磁盘垃圾,直接内存)
        
        被PhantomReference对象引用的对象称为虚引用对象
        当gc垃圾回收时,无论内存是否充足,都会回收虚引用关联的对象。
            就会将引用对象放入引用队列,会有线程来定时清理
        
        
        虚引用唯一的作用就是对垃圾回收过程进行跟踪,当虚引用对象引用的对象被垃圾回收了
            就将虚引用对象和垃圾地址加入引用队列,
            然后java会定时来引用队列中查找任务,定时执行
            如:调用方法Unsafe.freeMemory(addr),清理其中的 直接内存

        在jvm中对 对外内存 的回收就是利用虚引用来实现。具体看堆外内存管理部分。

    终结器引用    第二次  GC 时才回收
        
        终结器引用和虚引用的方式很类似,它用来实现对象的finaliz()终结方法。

        所有的类有父类Object类,Object类中有finaliz()终结方法

        当对象重写了finaliz()终结方法后,对象没有强引用时
        虚拟机 会自动为对象创建终结器引用,
        当对象被gc垃圾回收时,先将终结器引用放到引用队列中
        再用优先级别很低的线程finaliz handle线程来查询引用队列中有没有终结器引用
        如果有,该线程就会调用finaliz()方法,执行终结方法
        第二次 GC 时才回收被引用的对象。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值