java面试-强引用、软引用、弱引用和幻象引用有什么区别
在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面试-强引用、软引用、弱引用和幻象引用有什么区别的更多相关文章
- Java中强、软、弱、虚引用
1.强引用(StrongReference) 强引用是使用最普遍的引用.如果一个对象具有强引用,那垃圾回收器绝不会回收它.当内存空间不足,Java虚拟机宁愿抛出OutOfMemoryError错误,使 ...
- 0030 Java学习笔记-面向对象-垃圾回收、(强、软、弱、虚)引用
垃圾回收特点 垃圾:程序运行过程中,会为对象.数组等分配内存,运行过程中或结束后,这些对象可能就没用了,没有变量再指向它们,这时候,它们就成了垃圾,等着垃圾回收程序的回收再利用 Java的垃圾回收机制 ...
- Java:对象的强、软、弱、虚引用
转自: http://zhangjunhd.blog.51cto.com/113473/53092 1.对象的强.软.弱和虚引用 在JDK 1.2以前的版本中,若一个对象不被任何变量引用,那么程序就无 ...
- Java中四种引用:强、软、弱、虚引用
这篇文章非常棒:http://alinazh.blog.51cto.com/5459270/1276173 Java中四种引用:强.软.弱.虚引用 1.1.强引用当我们使用new 这个关键字创建对象时 ...
- Java:对象的强、软、弱和虚引用
1.对象的强.软.弱和虚引用 在JDK 1.2以前的版本中,若一个对象不被任何变量引用,那么程序就无法再使用这个对象.也就是说,只有对象处于可触及(reachable)状态,程序才能使用它.从JDK ...
- Java对象的强、软、弱和虚引用详解
1.对象的强.软.弱和虚引用 转自:http://zhangjunhd.blog.51cto.com/113473/53092/ 在JDK 1.2以前的版本中,若一个对象不被任何变量引用,那么程序就无 ...
- java基础知识再学习--集合框架-对象的强、软、弱和虚引用
原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任.http://zhangjunhd.blog.51cto.com/113473/53092 本文 ...
- Java对象的强、软、弱和虚引用原理+结合ReferenceQueue对象构造Java对象的高速缓存器
//转 http://blog.csdn.net/lyfi01/article/details/6415726 1.Java对象的强.软.弱和虚引用 在JDK 1.2以前的版本中,若一个对象不被任何变 ...
- Java:对象的强、软、弱和虚引用[转]
原文链接:http://zhangjunhd.blog.51cto.com/113473/53092/ 原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法 ...
- Java对象的强、软、弱和虚引用+ReferenceQueue
Java对象的强.软.弱和虚引用+ReferenceQueue 一.强引用(StrongReference) 强引用是使用最普遍的引用.如果一个对象具有强引用,那垃圾回收器绝不会回收它.当内存空间不足 ...
随机推荐
- Flutter & QRCode App
Flutter & QRCode App https://github.com/xgqfrms/qrcode-reader-app how to open android emulator o ...
- js & disabled right click & disabled right menu
js & disabled right click (() => { const log = console.log; log(`disabled copy`); document.bo ...
- C# 类中操作主窗体控件
主窗体程序: using System; using System.Collections.Generic; using System.ComponentModel; using System.Dat ...
- c# winform中窗体切换后释放及防止重复生成
问题1:窗体切换后如何关闭,并释放资? c# winform中,2个窗体,form1和form2,互相切换的时候执行 this.Hide(); Form2 form2 = new Form2(); f ...
- Debian 基本使用进阶
系统安装好了我们,迫不及待的想要在Linux系统中肆意翱翔.如果是刚刚接触Linux的系统的话,可能一时间还无法适应Linux的系统环境.对于使用Debian来做服务器的选择,最好的练习方式的就是使用 ...
- 为什么数据库能查出两条id相同的数据
sql如下: SELECT t.*,d.name as "workName" FROM t_traceability_slice t LEFT JOIN sys_departmen ...
- HDOJ-3038(带权并查集)
How many answers wrong HDOJ-3038 一个很好的博客:https://www.cnblogs.com/liyinggang/p/5327055.html #include& ...
- 创建一个scrapy爬虫框架的项目
第一步:打开pycharm,选择"terminal",如图所示: 第二步:在命令中端输入创建scrapy项目的命令:scrapy startproject demo (demo指的 ...
- 03-Spring默认标签解析
默认标签的解析 上一篇分析了整体的 xml 文件解析,形成 BeanDefinition 并注册到 IOC 容器中,但并没有详细的说明具体的解析,这一篇主要说一下 默认标签的解析,下一篇主要说自定义标 ...
- 超详细Linux新手快速入门(一)——Linux的介绍安装以及虚拟机的介绍安装
一.Linux的介绍 1.Linux和Windows的比较 Linux是一款操作系统,其性能稳定,因其防火墙组件高效安全.简单易配置,所以获得了追求速度和安全的一些企业和人群的青睐.与我们日常所熟知 ...