A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

Java中强引用、软引用、弱引用、虚引用各是什么东东呀?它们各自垃圾回收机制是什么?

评分

参与人数 1技术分 +1 收起 理由
黄玉昆 + 1 鼓励鼓励

查看全部评分

5 个回复

倒序浏览
java.lang.ref包下分别有PhantomReference(虚引用)、SoftReference(软引用)、WeakReference(弱引用)。
回复 使用道具 举报
Object object=new Object()这样的强引用,垃圾回收器是不会回收,其它几种呢?
回复 使用道具 举报
http://blog.csdn.net/liuxian13183/article/details/8636069
回复 使用道具 举报
首先明确一点,这些引用类型的产生就像毕老师说的,是为了优化内存。具体如下:

强引用:这是java中最常见的引用方式,创建一个对象并把这个这对赋给一个相应类型的变量,这个引用变量就是强引用。被强引用的对象绝对不会被垃圾回收机制回收,哪怕内存资源紧缺,所以这也是造成内存泄露的主要原因之一,建议对象用完以后置为null。

软引用:需要通过SorftReference类来实现(详见JDK),例如
SorftReference sr = new SorftReference(传入你要引用的对象);
对于此类引用,当内存足够时不会被垃圾回收机制干掉,这时与强引用没什么区别,该对象可正常使用,但内存紧张时就会被回收不管你用完没用完,通常在一些内存敏感的程序中,它算是强引用的很好替代。

弱引用:弱引用与软引用有些类似,不过它没有软引用坚强,对于只有弱引用的对象,当进行垃圾回收时,不管内存充足与否都会被干掉,此类引用通过WeakReference类实现,用法同上。

虚引用:此引用通过PhantomReference类实现,虚引用完全类似于没有引用。软引用和若引用可以单独使用,但是虚引用不可以,使用它也没太大意义。他的主要作用就是用于跟踪对象被垃圾回收的状态,需要和引用队列(ReferenceQueue)类联合使用,来检查引用队列中是否已经包含指定的虚引用,从而了解虚引用所引用对象是否即将被回收。


说到这就要讲一下这个引用队列(ReferenceQueue)类是什么玩意儿啦,他用于保存被回收后对象的引用。当把软引用,若引用与该队列联合使用时,系统回收被引用的对象后,将会把这些对象对应的引用添加到该队列中。但是!但是!但是!虚引用就不同啦,虚引用是在对象被释放之前,注意啦哈,是之前,将把对应引用添加到他所关联的引用队列中,这样就可以通过查找来完成确认该引用是否即将被回收,也就可以再其被回收之前做些业务需要的处理啦!

评分

参与人数 1技术分 +1 收起 理由
黄玉昆 + 1 赞一个!最好给出代码,就完美了.

查看全部评分

回复 使用道具 举报
楼上哥们儿说得在理,查了些资料,确实是。实验了以下,如下:
代码一:
    String str = new String("Hi");
    ReferenceQueue rq = new ReferenceQueue();
    WeakReference wf = new WeakReference(str, rq);   
    str=null;  
    String str1=(String) wf.get();
    System.out.println("str1:"+str1);
此时,输出结果为:
    str1:Hi


代码二:
    String str = new String("Hi");
    ReferenceQueue rq = new ReferenceQueue();
    WeakReference wf = new WeakReference(str, rq);   
    str=null;  
    System.gc();
    String str1=(String) wf.get();
    System.out.println("str1:"+str1);

此时,输出结果为:
    str1:null
证明弱引用在垃圾回收时被清掉了。

代码三:
    String str = new String("Hi");
    ReferenceQueue rq = new ReferenceQueue();
    SoftReference<String> sr=new SoftReference<String>(str);   
    str=null;  
    String str2=sr.get();
    System.out.println("str2:"+str2);

此时,输出结果为:
    str2:Hi


代码四:
    String str = new String("Hi");
    ReferenceQueue rq = new ReferenceQueue();
    SoftReference<String> sr=new SoftReference<String>(str);   
    str=null;  
    System.gc();
    String str2=sr.get();
    System.out.println("str2:"+str2);

此时,输出结果为:
    str2:Hi

证明软引用垃圾回收时没被清掉,只是不知道如何模拟内存不足时清掉软引用的?

另外,如下代码垃圾回收时弱引用也没被清掉,不知为何?
    String str = new String("Hi");
                ReferenceQueue rq = new ReferenceQueue();
                WeakReference wf = new WeakReference(str, rq);
                SoftReference<String> sr=new SoftReference<String>(str);
                str=null;               
                System.gc();
                System.gc();       
                String str2=sr.get();
                String str1=(String) wf.get();               
                System.out.println("str1:"+str1);
                System.out.println("str2:"+str2);
输出结果为:
        str1:Hi
        str2:Hi
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马