JAVA基础 - 强引用、弱引用、软引用、虚引用

前言

Java执行 GC(垃圾回收)判断对象是否存活有两种方式,分别是引用计数法引用链法(可达性分析法)

引用计数:Java堆中给每个对象都有一个引用计数器,每当某个对象在其它地方被引用时,该对象的计数器 +1;引用失效则 -1;

JDK 1.2版本开始,对象的引用被划分为 4种级别,使程序能更加灵活地控制对象的生命周期。这 4种级别由高到低依次为:强引用软引用弱引用虚引用。 

正文

(一) 强引用(StrongReference)

在一个线程内,无须引用直接可以使用的对象,强引用不会被JVM清理。我们平时申明变量使用的就是强引用,普通系统99%以上都是强引 用,比如,String s="Hello World"。

Java中的引用,有点像 C++的指针。通过引用,可以对堆中的对象进行操作。在Java 程序中,最常见的引用类型是强引用,它也是默认的引用类型。例如:StringBuffer str=new StringBuffer(“Hello World”);
当在Java语言中使用new 操作符创建一个新的对象,并将其赋值给一个变量的时候,这个变量就成为指向该对象的一个强引用。而判断一个对象是否存活的标准为是否存在指向这个对象的引用。

强引用具备以下特点
(1)强引用可以直接访问目标对象。
(2)强引用所指向的对象在任何时候都不会被系统回收。JVM宁愿抛出Out Of Memory异常也不会回收强引用所指向的对象。
(3)强引用可能导致内存泄漏。

通常来说,应用程序内部的内存泄露两种情况。一种是虚拟机中存在程序无法使用的内存区域,另一种情况是程序中存在大量存活时间过长的对象。

(二) 软引用(SoftReference)

java中使用SoftRefence来表示软引用

软引用是除了强引用外最强的引用类型,我们可以通过java.lang.ref.SoftReference使用软引用。一个持有软引用的对象,它不会被JVM很快回收,JVM会根据当前堆的使用情况来判断何时回收。当堆使用率临近阙值时,才会去回收软引用的对象。只要有足够的内 存,软引用便可能在内存中存活相当长一段时间。通过软引用,垃圾回收器就可以在内存不足时释放软引用可达的对象所占的内存空间。保证程序正常工作。

通过一个软引用申明,JVM抛出OOM之前,清理所有的软引用对象。垃圾回收器某个时刻决定回收软可达的对象的时候,会清理软引用,并可选的把引用存放到一个引用队列(ReferenceQueue)。

(三) 弱引用(WeakReference)

java中使用WeakReference来表示弱引用。如果某个对象与弱引用关联,那么当JVM在进行垃圾回收时,无论内存是否充足,都会回收此类对象。

通过一个弱引用申明。类似弱引用,只不过 Java 虚拟机会尽量让软引用的存活时间长一些,迫不得已才清理。

(四) 虚引用(PhantomReference)

java中使用PhantomReference来表示虚引用。

通过一个虚引用申明。仅用来处理资源的清理问题,比Object里面的finalize机制更灵活。get方法返回的永远是null,Java虚拟机不负责清理虚引用,但是它会把虚引用放到引用队列里面。

虚引用的主要目的是在一个对象所占的内存被实际回收之前得到通知,从而可以进行一些相关的清理工作。弱引用之前的两种引用类型有很大的不同:首先虚引用在创建时必须提供一个引用队列作为参数;其次虚引用对象的get方法总是返回null,因此无法通过虚引用来获取被引用的对象。

代码

        //强引用
        String S = "强 引用 森";
        //软引用
        SoftReference<String> stringSoftReference = new SoftReference<>(new String("软 引用 仔"));
        System.out.println(stringSoftReference.get());
        System.gc();
        System.out.println(stringSoftReference.get());
        //弱引用
        WeakReference<String> str = new WeakReference<>("弱reference 森");
        System.out.println(str.get());
        System.gc();  //通知JVM进行内存回收
        System.out.println(str.get());
        //虚引用
        ReferenceQueue<Object> queue = new ReferenceQueue<>();
        PhantomReference<String> strs = new PhantomReference<>("虚引用 ", queue);
        System.out.println(strs.get());
        System.out.println(S);

打印内容:
软 引用 仔
软 引用 仔
弱reference 森
null
null
强 引用 森

总结

Java中 4种引用的级别和强度由高到低依次为:强引用 -> 软引用 -> 弱引用 -> 虚引用

垃圾回收器回收时,某些对象会被回收,某些不会被回收。垃圾回收器会从根对象 Object来标记存活的对象,然后将某些不可达的对象和一些引用的对象进行回收。

表格说明如下:

引用类型被垃圾回收时间用途生存时间
强引用从来不会对象的一般状态JVM停止运行时终止
软引用当内存不足时对象缓存内存不足时终止
弱引用正常垃圾回收时对象缓存垃圾回收后终止
虚引用正常垃圾回收时跟踪对象的垃圾回收垃圾回收后终止


人无完人,接受指点与反驳,森!!仔

  • 23
    点赞
  • 154
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值