简述Java中的四种引用类型
作者:布禾 发布时间:2023-11-29 00:46:56
目录
简介
强引用
软引用
弱引用
虚引用
简介
从JDK1.2版本开始,把对象的引用分为四种级别,从而使程序能更加灵活的控制对象的生命周期。这四种级别由高到低依次为:强引用、软引用、弱引用和虚引用,下面分别介绍下这四种引用。
强引用
强引用是最常用的引用类型,如下所示,new Object()会创建一个Object对象并存储在堆上,变量object存储对该对象的强引用。
Object object = new Object();
强引用不会被垃圾回收,所以要想回收该对象,则应该将指向该对象的变量显示设为null,这样该对象就由强引用转变为无引用了。
示例:
public class ReferenceDemo {
public static void main(String[] args) throws IOException {
//强引用不会被垃圾回收
ReferenceDemo referenceDemo = new ReferenceDemo();
//强引用转变为无引用,无引用可被垃圾回收
referenceDemo = null;
//触发垃圾回收
System.gc();
//阻塞主线程,等待垃圾回收线程执行
System.in.read();
}
//对象被回收之前调用
@Override
protected void finalize() throws Throwable {
super.finalize();
System.out.println("-----finalize-----");
}
}
软引用
软引用是使用SoftReference创建的,在内存空间充足的情况下,软引用不会被回收,而在内存空间不足虚拟机抛出OutOfMemoryError之前,软引用将会被回收。
示例:
public class ReferenceDemo {
public static void main(String[] args) throws InterruptedException {
//创建ReferenceDemo对象的软引用
SoftReference<ReferenceDemo> softReference = new SoftReference<>(new ReferenceDemo());
//触发垃圾回收
System.gc();
//阻塞主线程,等待垃圾回收线程执行
Thread.sleep(5000);
//softReference.get()返回软引用对象,如果对象已经被垃圾回收,则返回null
System.out.println(softReference.get());
//创建25M的字节数组
byte[] bytes = new byte[1024 * 1024 * 25];
//内存已经不足,阻塞主线程,等待垃圾回收线程执行
Thread.sleep(5000);
//重新输出软引用对象
System.out.println(softReference.get());
}
}
/*
* 输出结果:
* com.buhe.demo.demos.reference.ReferenceDemo@76fb509a
* null
*/
注意:示例运行前需要设置堆内存大小为30M(-Xmx30m -Xms30m)。
用途:软引用可以用于对内存空间敏感的缓存,缓存的对象一直保存,直到内存空间不足而被回收。
弱引用
弱引用是使用WeakReference创建的,在垃圾回收线程执行过程中,只要找到了弱引用,不管内存空间是否足够,弱引用对象都将被回收。由于垃圾回收线程是一个优先级很低的线程,因此不一定会很快发现那些只具有弱引用的对象。
示例:
public class ReferenceDemo {
public static void main(String[] args) throws InterruptedException {
//创建ReferenceDemo的弱引用
WeakReference<ReferenceDemo> weakReference = new WeakReference<>(new ReferenceDemo());
//weakReference.get()返回弱引用对象,如果对象已经被垃圾回收,则返回null
System.out.println(weakReference.get());
//触发垃圾回收
System.gc();
//阻塞主线程,等待垃圾回收线程执行
Thread.sleep(3000);
//重新输出弱引用对象
System.out.println(weakReference.get());
}
}
/*
* 输出结果:
* com.buhe.demo.demos.reference.ReferenceDemo@76fb509a
* null
*/
用途:弱引用也可以用于缓存,可以参考WeakHashMap类。
虚引用
虚引用是使用PhantomReference创建的,它是所以引用类型中最弱的。虚引用对象和没有引用的对象相同,可以在任何时候被垃圾回收,并且虚引用必须要与引用队列一起使用。
当垃圾回收线程回收一个虚引用对象时,它将在垃圾回收后销毁该对象,并将PhantomReference添加到引用队列中。
示例:
public class ReferenceDemo {
public static void main(String[] args) throws InterruptedException {
//创建引用队列
ReferenceQueue<Object> referenceQueue = new ReferenceQueue();
//创建ReferenceDemo的虚引用
PhantomReference<ReferenceDemo> phantomReference = new PhantomReference<>(new ReferenceDemo(), referenceQueue);
//phantomReference.get()总是返回null
System.out.println("phantomReference.get():" + phantomReference.get());
//轮询此队列,查看是否有可用的Reference对象,有则返回该对象,否则返回null
System.out.println("referenceQueue.poll():" + referenceQueue.poll());
//触发垃圾回收
System.gc();
//阻塞主线程,等待垃圾回收线程执行
Thread.sleep(3000);
System.out.println("------垃圾回收之后------");
System.out.println("phantomReference.get():" + phantomReference.get());
System.out.println("referenceQueue.poll():" + referenceQueue.poll());
}
}
/*
* 输出结果:
* phantomReference.get():null
* referenceQueue.poll():null
* ------垃圾回收之后------
* phantomReference.get():null
* referenceQueue.poll():java.lang.ref.PhantomReference@76fb509a
*/
用途:虚引用可以用于精确的检测对象何时从内存中删除,通过检查引用队列来判断对象是否已经被回收。
来源:https://www.cnblogs.com/seve/p/14634520.html


猜你喜欢
- 存储访问框架,简称:SAF, 就是系统文件选择器+文件操作API。先选择文件,在用文件操作API处理文件。系统文件选择器,就和Windows
- 本文实例讲述了Java设计模式之工厂模式。分享给大家供大家参考,具体如下:一、 简单工厂先来思考一个问题。我们平时写程序时,会有这种情况,A
- 前言;Apache common-pool对象池介绍:对象生命周期、Config详解、代码说明对象生命周期Config详解maxActive
- 1、需求及配置需求:爬取京东手机搜索页面的信息,记录各手机的名称,价格,评论数等,形成一个可用于实际分析的数据表格。使用Maven项目,lo
- Android实现读取NFC卡卡号示例,具体如下:1.权限 <uses-permission android:name=&
- 我计划在后续的一段时间内,写一系列关于java 9的文章,虽然java 9 不像Java 8或者Java 11那样的核心java版本,但是还
- SEATA概要seata 是alibaba 出的一款分布式事务管理器,他有侵入性小,实现简单等特点。我们能够使用seata 实现分布式事务管
- 概述在Spring中,我们可以通过 @Autowired注解的方式为一个方法中注入参数,那么这种方法背后到底发生了什么呢,这篇文章将讲述如何
- 员工管理系统1、准备工作资料下载内含源码 + 笔记 + web素材源码下载地址:http://xiazai.jb51.net/202105/
- 1.常用属性Name:名称;BackColor:设置控件背景颜色;Enabled:是否可用;FlayStyle:控件样式;Image:设置控
- 基本要点1、Lombok作用:在我们的实体类中,我们再也不需要声明get、set、有参无参等方法,统统可以通过Lombok注解来实现同样的功
- 操作步骤如下一、dropzone导入01.dropzone官网下载其插件压缩包并复制项目;02.将CSS和JS文件在HTML文件中引入;//
- 前言:最近公司C轮融资成功了,移动团队准备扩大一下,需要招聘Android开发工程师,陆陆续续面试了几位Android应聘者,面试过程中聊到
- 这几天Java项目中需要用到Redis,于是学习了一下使用Jedis来操作Redis服务器的相关知识,下面为具体的配置和代码。1、Maven
- 本文实例为大家分享了Unity3D Ui利用shader添加效果的具体代码,供大家参考,具体内容如下// Upgrade NOTE: rep
- 前言对于联表查询的四个注解 @OneToOne、@OneToMany、@ManyToOne 和 @ManyToMany,他们有几个用得比较多
- java Long类型转为String类型1、Long.ValueOf("String")返回Long包装类型数据包装类
- 本文实例讲述了C#使用有道ip地址查询接口方法。分享给大家供大家参考。具体实现方法如下:#region 读取http://www.yodao
- 本人工作有一个月多了。对于android很多东西,都有了新的了解或者说真正的掌握。为了让更多的像我这样的小白少走弯路,所以我会坚持将我在工作
- Activity的跳转动画在5.0的时候做了一个重大的突破,下面来看一下吧1.5.0之前的overridePendingTransition