强引用、软引用、弱引用、虚引用的区别 -Java_强引用软引用弱引用虚引用的区别-程序员宅基地

技术标签: JVM  jvm  java  

Java中为何要分别定义强引用、软引用、弱引用、虚引用四种引用类型?

我们对于对象的定义不能只局限于“引用”和“未被引用”两种状态,因为我们还存在几种引用类型能描述这样一类对象:当内存空间还足够时,仍保留在内存之中,如果内存空间在进行垃圾收集后仍然非常紧张,那就可以抛弃这些对象(这类对象应用在很多系统的缓存功能上)。

在JDK 1.2版之后,Java对引用的概念进行了扩充,将引用分为强引用(Strongly Re-ference)、软引用(Soft Reference)、弱引用(WeakReference)和虚引用(Phantom Reference)4种,这4种引用强度依次逐渐减弱。

定义这四种引用类型的目的:

1.让程序员通过代码的方式决定某些对象的生命周期;
2.有利于JVM进行垃圾回收。

强引用:必不可少的,不会被垃圾回收器进行回收的。

当内存空间不足的时候,程序宁愿抛出java.lang.OutOfMemoryError错误,使程序异常终止,也不回收这种对象。

 public static void main(String[] args) {
    
        Object[] objects=new Object[Integer.MAX_VALUE];  
    }
"C:\Program Files\Java\jdk1.8.0_192\bin\java.exe" "-javaagent:C:\Program Files\JetBrains\IntelliJ IDEA 2020.1.3\lib\idea_rt.jar=6744:C:\Program Files\JetBrains\IntelliJ IDEA 2020.1.3\bin" ...Day27.TestDemo
Exception in thread "main" java.lang.OutOfMemoryError: Requested array size exceeds VM limit
	at Day27.TestDemo.main(TestDemo.java:5)

Process finished with exit code 1

如果想要中断强引用和某个对象之间的联系的时候,可以显示的将引用赋值为null,这样,JVM在合适的时间就会回收该对象。

软引用:有用但不是必需的对象。

SoftReference类
只被软引用关联着的对象,在系统将要发生内存溢出异常前,会把这些对象列进回收范围之中进行第二次回收,如果这次回收还没有足够的内存,才会抛出内存溢出异常。只有在内存空间不足的时候,Java虚拟机才会回收该对象,如一些网页缓存,图片缓存就使用的软引用。

public static void main(String[] args) throws InterruptedException {
    
        //创建方式
        Object obj = new Object();
        SoftReference<Object> sf = new SoftReference<Object>(obj);
        //使用方式
        Object obj1 = sf.get();
        //说明没有被回收
        if(obj1 != null) obj1.wait();//使用对象

    }

弱引用:非必需的对象。

WeakReference类
被弱引用关联的对象只能生存到下一次垃圾收集发生为止,等下一次垃圾回收回收的时候,无论JVM内存空间是否充足,都会回收被弱引用关联的对象。

弱引用和软引用的区别:
生存周期不同:弱引用的对象拥有更短暂的生命周期,在垃圾回收器扫描它所管辖的内存区域的过程中,一旦发现了具有弱引用的对象,不管当前内存是否足够,都会进行回收它。垃圾回收器是一个优先级很低的线程,因此不一定会发现那些只具有弱引用的对象,所以被软引用关联的对象只有在内存空间不足的时候才会被回收,而被弱引用关联的对象在JVM进行垃圾回收时总会被回收。

虚引用:最弱的一种引用,如同虚设一样

一个对象是否有虚引用的存在,完全不会对其生存时间构成影响,也无法通过虚引用来取得一个对象实例。为一个对象设置虚引用关联的唯一目的只是为了能在这个对象被收集器回收时收到一个系统通知。
PhantomReference类

总结:

引用类型 被垃圾回收的时间 用途 生存时间
强引用 从来不会 对象的一般状态 JVM停止运行时终止
软引用 在内存不足时 对象缓存 内存不足时终止
弱引用 在垃圾回收时 对象缓存 GC运行后终止
虚引用 未知 让这个对象被收集器回收时收到一个系统通知 未知

强引用:
不会被回收的对象。
软引用:
如果弱引用对象回收完之后,内存还是报警,继续回收软引用对象
弱引用:
如果虚引用对象回收完之后,内存还是报警,继续回收弱引用对象
虚引用:
虚拟机的内存不够使用,开始报警,这时候垃圾回收机制开始执行System.gc(); 如果没有对象回收了,就回收没虚引用的对象

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/m0_46551861/article/details/115260635

智能推荐

YV12,I420,YUV420P的区别-程序员宅基地

文章浏览阅读43次。2019独角兽企业重金招聘Python工程师标准>>> ..._yv12和iyuv的区别

ubuntu安装neo4j数据库-直接安装与docker方式_neo4j: line 418: /data/workspace/datafactory/neo4j-程序员宅基地

文章浏览阅读568次。本文介绍了ubuntu下分别使用源安装和docker安装neo4j的方法添加下载源安装wget -O - https://debian.neo4j.org/neotechnology.gpg.key | sudo apt-key add -echo 'deb https://debian.neo4j.org/repo stable/' | sudo tee /etc/apt/sources...._neo4j: line 418: /data/workspace/datafactory/neo4j/neo4j-community-3.4.5/run

正则表达式(一)——验证电话号码_判断电话号码的正则表达式-程序员宅基地

文章浏览阅读3.3w次。正则表达式:注意:1.比如你要验证电话号码是否正确,要求是:以1开头,第2位是3,5,8,总共11位 正则表达式应该书写成 ^[1]+[3,8]+\d{9}$package com.ld.num;import java.util.regex.Matcher;import java.util.regex.Pattern;public class Telephone {..._判断电话号码的正则表达式

Unity3D项目程序加密-VirboxProtector加壳工具_unity shield加壳-程序员宅基地

文章浏览阅读6k次。各位Unity3D的开发者,你还为你的代码被反编译而头疼, 混淆和加密已经失效,为内存dump代码而烦恼?是否辛苦制作的游戏被盗版被抄袭而烦恼? 是否害怕算法被别人参考要把算法写成C++而费劲周折?快来使用深思数盾外壳保护(Sense Shield Virbox Protector ) 专门处理Unity3D的代码加密和授权保护。 背景: 大家都知道Unit_unity shield加壳

Linux下搭建Git服务器详细步骤 + eclipse当中Git的使用,模拟过程_linux上如何搭建自己的git服务器-程序员宅基地

文章浏览阅读927次,点赞30次,收藏27次。入程序员的圈子,让我们一起学习成长!_linux上如何搭建自己的git服务器

C语言杂记3_movc字节数-程序员宅基地

文章浏览阅读381次。四、数据类型标识符 区分大小写,首字母为字母或下划线关键字 具有固定名称和含义char 通常用于定义处理字符数据的变量或常量,默认值为signed char 类型。signed char 类型用字节中最高位字节表示数据的符号,“0”表示正数,“1”表示负数,负数用补码表示。*正数的补码与原码相同,负二进制数的补码等于它的绝对值按位取反后加 1。int 默认值为signed int 类型,..._movc字节数

随便推点

热点!《北京市电子印章推广应用行动方案(试行)》发布_电子印章推广方案-程序员宅基地

文章浏览阅读220次。12月4日,北京市经济和信息化局、市政务服务管理局、市公安局联合印发《北京市电子印章推广应用行动方案(试行)》(以下简称《行动方案》)。《行动方案》提出,以“统一管理、分步实施、政府带动、并行过渡”为原则,以政务服务领域电子印章应用为突破口,推进电子印章在企业提交可信材料、政府全程在线审批等业务场景中的便捷应用,逐步构建“互联网+”环境下政府管理和服务方式;鼓励政府和企业使用存储在云端的电子印章(简称云章),减少纸质材料和实体印章使用,建立程序更便利、资源更集约的政务服务新模式。《行动方.._电子印章推广方案

Android实现退出整个程序的方法_activity直接退出整个app-程序员宅基地

文章浏览阅读1.3k次。这里采用任务栈管理器的方式,即利用一个单例模式的Activity栈来管理所有Activity。实现步骤 1. 自定义 Application类,储存每一个Activity,并实现关闭所有Activity的操作;import android.app.Activity;import android.app.Application;import java.util.LinkedList;import java.util.List;public class..._activity直接退出整个app

【GUI软件】小红书评论采集:自动采集10000多条,含二级评论!-程序员宅基地

文章浏览阅读1.3k次,点赞14次,收藏15次。为什么有了源码还开发界面软件呢?方便不懂编程代码的小白用户使用,无需安装python,无需改代码,双击打开即用!我用python开发了一个爬虫采集软件,可自动抓取小红书评论数据,并且含二级评论数据。通过把已有代码部分封装成class类,供tkinter界面调用。好的日志功能,方便软件运行出问题后快速定位原因,修复bug。完整python源码及exe软件,微信公众号"软件界面采用tkinter开发。,一名10年程序猿。_小红书评论采集

cuda java_在Nvidia GPU上使用Java(CUDA)-程序员宅基地

文章浏览阅读1k次。小编典典首先,你应该意识到CUDA不会自动加快计算速度这一事实。在一方面,由于GPU编程是一门艺术,它可以是非常,非常具有挑战性得到它的权利。另一方面,因为GPU仅适合某些类型的计算。这听起来可能令人困惑,因为你基本上可以在GPU上进行任何计算。关键当然是你是否会实现良好的加速。这里最重要的分类是问题是任务并行还是数据并行。粗略地说,第一个是指多个线程正在或多或少地独立执行各自任务的问题。第二个问..._java调用nvidia显卡

arcgis10.2发布要素服务(feature service)_gis10.2可以发要素服务吗-程序员宅基地

文章浏览阅读2.8k次。一、创建地理数据库1.需要安装ArcSDE2.在arcCatalog里创建地理数据库 二、ArcGIS Server 注册托管数据库1.添加一个数据库连接 2.在server里注册托管数据库 在arcCatalog里右键选server properties_gis10.2可以发要素服务吗

ubuntu下conda如何设置镜像源(清华镜像源)_ubuntu conda 设置镜像-程序员宅基地

文章浏览阅读2.4k次,点赞10次,收藏19次。首先贴出.condarc,直接给出清华的镜像源,需要的小伙伴直接使用,别看内容了添加conda镜像源命令(直接使用)接下来开始慢慢介绍了。_ubuntu conda 设置镜像