在Java语言中,除了基本数据类型外,其他的都是指向各类对象的对象引用;Java中根据其生命周期的长短,将引用分为4类。

不同的引用类型,主要体现的是对象不同的可达性状态和对垃圾收集的影响。

1 、强引用

我们平常典型编码Object obj = new Object()中的obj就是强引用。通过关键字new创建的对象所关联的引用就是强引用。

当JVM内存空间不足,JVM宁愿抛出OutOfMemoryError运行时错误(OOM),使程序异常终止,也不会靠随意回收具有强引用的“存活”对象来解决内存不足的问题。

对于一个普通的对象,如果没有其他的引用关系,只要超过了引用的作用域或者显式地将相应强引用赋值为 null,就是可以被垃圾收集的了,具体回收时机还是要看垃圾收集策略。

2 、软引用

软引用通过SoftReference类实现。 软引用的生命周期比强引用短一些。

只有当 JVM 认为内存不足时,才会去试图回收软引用指向的对象,即JVM 会确保在抛出 OutOfMemoryError 之前,清理软引用指向的对象。

软引用可以和一个引用队列(ReferenceQueue)联合使用,如果软引用所引用的对象被垃圾回收器回收,Java虚拟机就会把这个软引用加入到与之关联的引用队列中。

后续,我们可以调用ReferenceQueue的poll()方法来检查是否有它所关心的对象被回收。如果队列为空,将返回一个null,否则该方法返回队列中前面的一个Reference对象。

应用场景:软引用通常用来实现内存敏感的缓存。如果还有空闲内存,就可以暂时保留缓存,当内存不足时清理掉,这样就保证了使用缓存的同时,不会耗尽内存。

3、弱引用

弱引用通过WeakReference类实现。 弱引用的生命周期比软引用短。

不管当前内存空间足够与否,都会回收它的内存。由于垃圾回收器是一个优先级很低的线程,因此不一定会很快回收弱引用的对象。

弱引用可以和一个引用队列(ReferenceQueue)联合使用,如果弱引用所引用的对象被垃圾回收,Java虚拟机就会把这个弱引用加入到与之关联的引用队列

/**
* 弱引用所引用的对象被垃圾回收,Java虚拟机就会把这个弱引用加入到与之关联的引用队列中
*/
public class ReferenceQueueDemo {
public static void main(String[] args) throws InterruptedException {
Object object1 = new Object();
ReferenceQueue referenceQueue = new ReferenceQueue();
WeakReference<Object> weakReference = new WeakReference<>(object1,referenceQueue); System.out.println(object1);
System.out.println(weakReference.get());
System.out.println(referenceQueue.poll()); System.out.println("=====================");
object1 = null;
System.gc();
TimeUnit.SECONDS.sleep(1); System.out.println(object1);
System.out.println(weakReference.get());
System.out.println(referenceQueue.poll());
}
}  

应用场景:弱应用同样可用于内存敏感的缓存。

4 虚引用

虚引用也叫幻象引用,通过PhantomReference类来实现。

如果一个对象仅持有虚引用,那么它就和没有任何引用一样,在任何时候都可能被垃圾回收器回收。

无法通过虚引用访问对象的任何属性或函数。仅仅是提供了一种确保对象被 finalize 以后,做某些事情的机制。

虚引用必须和引用队列 (ReferenceQueue)联合使用。当垃圾回收器准备回收一个对象时,如果发现它还有虚引用,就会在回收对象的内存之前,把这个虚引用加入到与之关联的引用队列中。

ReferenceQueue queue = new ReferenceQueue ();

PhantomReference pr = new PhantomReference (object, queue);

程序可以通过判断引用队列中是否已经加入了虚引用,来了解被引用的对象是否将要被垃圾回收。

如果程序发现某个虚引用已经被加入到引用队列,那么就可以在所引用的对象的内存被回收之前采取一些程序行动。

应用场景:可用来跟踪对象被垃圾回收器回收的活动,当一个虚引用关联的对象被垃圾收集器回收之前会收到一条系统通知。

public class PhantomReferenceDemo {
public static void main(String[] args) throws InterruptedException {
Object object1 = new Object();
ReferenceQueue<Object> referenceQueue = new ReferenceQueue<>();
PhantomReference<Object> phantomReference = new PhantomReference<>(object1,referenceQueue); System.out.println(object1);
System.out.println(phantomReference.get());
System.out.println(referenceQueue.poll()); System.out.println("=====================");
object1 = null;
System.gc();
TimeUnit.SECONDS.sleep(1); System.out.println(object1);
System.out.println(phantomReference.get());
System.out.println(referenceQueue.poll());
}
}

  

java面试-强引用、软引用、弱引用和幻象引用有什么区别的更多相关文章

  1. Java中强、软、弱、虚引用

    1.强引用(StrongReference) 强引用是使用最普遍的引用.如果一个对象具有强引用,那垃圾回收器绝不会回收它.当内存空间不足,Java虚拟机宁愿抛出OutOfMemoryError错误,使 ...

  2. 0030 Java学习笔记-面向对象-垃圾回收、(强、软、弱、虚)引用

    垃圾回收特点 垃圾:程序运行过程中,会为对象.数组等分配内存,运行过程中或结束后,这些对象可能就没用了,没有变量再指向它们,这时候,它们就成了垃圾,等着垃圾回收程序的回收再利用 Java的垃圾回收机制 ...

  3. Java:对象的强、软、弱、虚引用

    转自: http://zhangjunhd.blog.51cto.com/113473/53092 1.对象的强.软.弱和虚引用 在JDK 1.2以前的版本中,若一个对象不被任何变量引用,那么程序就无 ...

  4. Java中四种引用:强、软、弱、虚引用

    这篇文章非常棒:http://alinazh.blog.51cto.com/5459270/1276173 Java中四种引用:强.软.弱.虚引用 1.1.强引用当我们使用new 这个关键字创建对象时 ...

  5. Java:对象的强、软、弱和虚引用

    1.对象的强.软.弱和虚引用 在JDK 1.2以前的版本中,若一个对象不被任何变量引用,那么程序就无法再使用这个对象.也就是说,只有对象处于可触及(reachable)状态,程序才能使用它.从JDK ...

  6. Java对象的强、软、弱和虚引用详解

    1.对象的强.软.弱和虚引用 转自:http://zhangjunhd.blog.51cto.com/113473/53092/ 在JDK 1.2以前的版本中,若一个对象不被任何变量引用,那么程序就无 ...

  7. java基础知识再学习--集合框架-对象的强、软、弱和虚引用

    原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任.http://zhangjunhd.blog.51cto.com/113473/53092 本文 ...

  8. Java对象的强、软、弱和虚引用原理+结合ReferenceQueue对象构造Java对象的高速缓存器

    //转 http://blog.csdn.net/lyfi01/article/details/6415726 1.Java对象的强.软.弱和虚引用 在JDK 1.2以前的版本中,若一个对象不被任何变 ...

  9. Java:对象的强、软、弱和虚引用[转]

    原文链接:http://zhangjunhd.blog.51cto.com/113473/53092/ 原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法 ...

  10. Java对象的强、软、弱和虚引用+ReferenceQueue

    Java对象的强.软.弱和虚引用+ReferenceQueue 一.强引用(StrongReference) 强引用是使用最普遍的引用.如果一个对象具有强引用,那垃圾回收器绝不会回收它.当内存空间不足 ...

随机推荐

  1. CodeMirror动态修改代码(关键: editor.getDoc().setValue(data); editor.refresh();)

    在使用codemirror时,其原理是根据form中的textarea标签,自动加载其内容,获得代码行的显示.(具体使用方式参见 codemirror官网使用手册 http://codemirror. ...

  2. Python学习笔记_斐波那契数列

    """ 1.生成100项斐波那契数列 2.求第n项斐波那契数列的值是多少 3.给定终止值,生成此前斐波那契数列 """ # 求第n项斐波那契 ...

  3. 微信小程序:应用生命周期

    小程序的生命周期分为应用生命周期和页面生命周期. 应用指的是一个文件,是小程序的入口文件app.js,入口文件最外层方法名称是App,页面的js文件最外层是page,组件的js文件的最外层是compo ...

  4. centos7.5+nginx+php急速配置

    centos7.5+nginx+php急速配置 centosnginxphp 更新系统以及添加源 yum update yum -y install epel-release 安装php以及配置 yu ...

  5. HDOJ-1260(动态规划水题)

    Tickets HDOJ-1260 #include<bits/stdc++.h> using namespace std; const int maxn=2003; int n; int ...

  6. CVE-2019-12409-Apache Solr JMX服务远程代码执行

    漏洞分析 https://www.freebuf.com/vuls/218730.html 漏洞介绍 该漏洞源于默认配置文件solr.in.sh中的ENABLE_REMOTE_JMX_OPTS配置选项 ...

  7. phpMyAdmin Transformation 任意文件包含/远程代码执行漏洞

    漏洞参考 https://yq.aliyun.com/articles/679633 国外提供了一个在线测试的靶场     默认密码  root  toor https://www.vsplate.c ...

  8. 微信小程序自定义Tabber,附详细源码

    目录 1,前言 2,说明 3,核心代码 1,前言 分享一个完整的微信小程序自定义Tabber,tabber按钮可以设置为跳转页面,也可以设置为功能按钮.懒得看文字的可以直接去底部,博主分享了小程序代码 ...

  9. windows 之间内网开启远程桌面连接

    win7设置远程桌面1.找到我的电脑\计算机图标,右键"属性"如图2.进入系统和安全设置-选项卡中,找到"远程设置"右上角位置点击打开3.在随后的"系 ...

  10. Docker 三剑客 到 k8s 介绍

    一.Docker 三剑客 Docker-Compose Docker-Compose 是用来管理你的容器的,有点像一个容器的管家,想象一下当你的Docker中有成百上千的容器需要启动,如果一个一个的启 ...