你知道Java的四种引用类型吗

在Java中提供了四个级别的引用:强引用,软引用,弱引用和虚引用。在这四个引用类型中,只有强引用FinalReference类是包内可见,其他三种引用类型均为public,可以在应用程序中直接使用。引用类型的类结构如图所示。

1.强引用

Java中的引用,类似C语言中最难的指针。(我是C语言入门编程,指针的概念还是很深入我心。)通过引用,可以对堆中的对象进行操作。如:

StringBuffer stringBuffer = new StringBuffer("Helloword");

变量str指向StringBuffer实例所在的堆空间,通过str可以操作该对象。

强引用的特点:

强引用可以直接访问目标对象。

强引用所指向的对象在任何时候都不会被系统回收。JVM宁愿抛出OOM异常,也不会回收强引用所指向的对象。

强引用可能导致内存泄漏。

2.软引用

软引用是除了强引用外,最强的引用类型。可以通过java.lang.ref.SoftReference使用软引用。一个持有软引用的对象,不会被JVM很快回收,JVM会根据当前堆的使用情况来判断何时回收。当堆使用率临近阈值时,才会去回收软引用的对象。因此,软引用可以用于实现对内存敏感的高速缓存。

SoftReference的特点是它的一个实例保存对一个Java对象的软引用, 该软引用的存在不妨碍垃圾收集线程对该Java对象的回收。也就是说,一旦SoftReference保存了对一个Java对象的软引用后,在垃圾线程对 这个Java对象回收前,SoftReference类所提供的get()方法返回Java对象的强引用。一旦垃圾线程回收该Java对象之后,get()方法将返回null。

下面举一个例子说明软引用的使用方法。

在你的IDE设置参数 -Xmx2m -Xms2m规定堆内存大小为2m。

    @Test

    public void test3(){

        MyObject obj = new myObject();

        SoftReference sf = new SoftReference<>(obj);

obj = null;

        System.gc();

//        byte[] bytes = new byte[1024*100];

//        System.gc();

System.out.println("是否被回收"+sf.get());

    }

运行结果:

是否被回收cn.zyzpp.MyObject@42110406

打开被注释掉的new byte[1024*100]语句,这条语句请求一块大的堆空间,使堆内存使用紧张。并显式的再调用一次GC,结果如下:

是否被回收null

说明在系统内存紧张的情况下,软引用被回收。

3.弱引用

弱引用是一种比软引用较弱的引用类型。在系统GC时,只要发现弱引用,不管系统堆空间是否足够,都会将对象进行回收。在java中,可以用java.lang.ref.WeakReference实例来保存对一个Java对象的弱引用。

    public void test3(){

        MyObject obj = new MyObject();

WeakReference sf = new WeakReference(obj);

        obj = null;

System.out.println("是否被回收"+sf.get());

        System.gc();

System.out.println("是否被回收"+sf.get());

    }

运行结果:

是否被回收cn.zyzpp.MyObject@42110406

是否被回收null

软引用,弱引用都非常适合来保存那些可有可无的缓存数据,如果这么做,当系统内存不足时,这些缓存数据会被回收,不会导致内存溢出。而当内存资源充足时,这些缓存数据又可以存在相当长的时间,从而起到加速系统的作用。

4.虚引用

虚引用是所有类型中最弱的一个。一个持有虚引用的对象,和没有引用几乎是一样的,随时可能被垃圾回收器回收。当试图通过虚引用的get()方法取得强引用时,总是会失败。并且,虚引用必须和引用队列一起使用,它的作用在于跟踪垃圾回收过程。

当垃圾回收器准备回收一个对象时,如果发现它还有虚引用,就会在垃圾回收后,销毁这个对象,将这个虚引用加入引用队列。程序可以通过判断引用队列中是否已经加入了虚引用,来了解被引用的对象是否将要被垃圾回收。如果程序发现某个虚引用已经被加入到引用队列,那么就可以在所引用的对象的内存被回收之前采取必要的行动。

    public void test3(){

        MyObject obj = new MyObject();

ReferenceQueue referenceQueue = new ReferenceQueue<>();

PhantomReference sf = new PhantomReference<>(obj,referenceQueue);

        obj = null;

System.out.println("是否被回收"+sf.get());

        System.gc();

System.out.println("是否被回收"+sf.get());

    }

运行结果:

是否被回收null

是否被回收null

对虚引用的get()操作,总是返回null,因为sf.get()方法的实现如下:

    public T get() {

        return null;

    }

5.WeakHashMap类及其实现

WeakHashMap类在java.util包内,它实现了Map接口,是HashMap的一种实现,它使用弱引用作为内部数据的存储方案。WeakHashMap是弱引用的一种典型应用,它可以作为简单的缓存表解决方案。

一下两段代码分别使用WeakHashMap和HashMap保存大量的数据:

    @Test

    public void test4(){

        Map map;

        map = new WeakHashMap();

        for (int i =0;i<10000;i++){

  map.put("key"+i,new byte[i]);

}

//        map = new HashMap();

//        for (int i =0;i<10000;i++){

//  map.put("key"+i,new byte[i]);

//}

    }

使用-Xmx2M限定堆内存,使用WeakHashMap的代码正常运行结束,而使用HashMap的代码段抛出异常

java.lang.OutOfMemoryError: Java heap space

由此可见,WeakHashMap会在系统内存紧张时使用弱引用,自动释放掉持有弱引用的内存数据。

但如果WeakHashMap的key都在系统内持有强引用,那么WeakHashMap就退化为普通的HashMap,因为所有的表项都无法被自动清理。

 为了让学习变得轻松、高效,今天给大家免费分享一套Java教学资源。帮助大家在成为Java架构师的道路上披荆斩棘。需要资料的欢迎加入学习交流群:9285,05736

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/503083.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

k8s学习 — (DevOps实践)第十三章 DevOps 环境搭建

k8s学习 — &#xff08;DevOps实践&#xff09;第十三章 DevOps 环境搭建 学习资料1 Gitlab1.1 安装 Gitlab1.2 页面配置1.3 配置 Secret1.4 为项目配置 Webhook1.5 卸载 2 Harbor2.1 安装 Harbor2.1 配置 Secret 3 SonarQube3.1 安装 SonarQube3.2 生成服务 token3.3 创建 We…

电脑打字学习_寒假就这样做!即不让孩子烦,还能让他有进步,开学就能迅速进入学习状态!...

部编本下册教材寒假预习可点击查看&#xff1a;六年级 五年级 四年级 三年级 二年级 一年级转眼间&#xff0c;一学期的学习又结束了&#xff0c;寒假模式正式开启。在这一个多月的寒假期间&#xff0c;孩子离开了学习&#xff0c;摆脱了老师的教育&#xff0c;如果家长再…

sap 供应商表_SAP系统玩阴的?

SAP系统玩阴的&#xff1f;近日和项目上的ABAP开发顾问一起弄一个自开发的报表。其中某个栏位的取值需要从批次主数据里抓取到供应商代码&#xff0c;然后根据供应商代码取到供应商名称等。为此笔者需要备功能说明书&#xff0c;在说明书里笔者需要将具体取值逻辑写清楚。要取到…

Java设计模式:单例模式

设计模式&#xff08;Design Pattern&#xff09;&#xff1a;是一套被反复使用&#xff0c;多数人知晓的&#xff0c;经过分类编目的&#xff0c;代码设计经验的总结。 目的&#xff1a;使用设计模式是为了可重用性代码&#xff0c;让代码更容易被他人理解&#xff0c;保证代…

滤波器的优点_声光可调谐滤波器

目前声光可调谐滤波器主要应用于光通信领域。它具有调谐速度快&#xff0c;可调谐范围宽、插入损耗低和通道驱动功率低等优点&#xff0c;并且可以实现多波长同时选择&#xff0c;因此在未来的波分复用网络中极有应用潜力。此外&#xff0c;声光可调谐滤波器还常用于半导体激光…

想学习大数据的同学一定要学习Java吗

一、学习大数据&#xff0c;一定要学习java吗? 首先&#xff0c;大家要清楚一点&#xff0c;学习Java的目的是什么&#xff0c;Java它本身是一门计算机编程语言&#xff0c;而进入大数据的学习&#xff0c;无论你有何基础&#xff0c;是零基础还是有过相关的学习经验&#xf…

qt多线程服务器_常见网络服务器并发模型

点击蓝字 关注我们近些年&#xff0c;随着互联网的大发展&#xff0c;高并发服务器技术也快速进步&#xff0c;从简单的循环服务器模型处理少量网络并发请求&#xff0c;演进到解决C10K&#xff0c;C10M问题的高并发服务器模型。本文主要以TCP为例&#xff0c;总结了几种常见的…

如何在vb.net中取得两时间的毫秒差_科技品牌软文营销如何写出一篇爆文?

随着互联网的发展&#xff0c;尤其是移动互联网的发展&#xff0c;让营销方式从传统的线下电视报纸广告逐渐转移到线上的软文营销。软文营销因为其快捷&#xff0c;方便&#xff0c;性价比高的特点受到了很多品牌的追捧。文章是软文营销的前提&#xff0c;如何写好一篇好的文章…

Java开发领域的大牛有哪些

Java开发领域的大牛有哪些 1、James Gosling 在他12岁的时候&#xff0c;他已能设计电子游戏机&#xff0c;帮忙邻居修理收割机。大学时期在天文系担任程式开发工读生&#xff0c;1977年获得了加拿大卡尔加里大学计算机科学学士学位&#xff0c;1983年获得了美国卡内基梅隆大学…

共阴极数码管编码表_数码管循环点亮的PLC控制——基本逻辑指令的应用

数码管循环点亮的PLC控制&#xff0c;我们运用日本三菱FX2N-48MR-001(FX2N-48MR-001是日本三菱公司的可编程控制器(PLC),继电器输出及输入24点,输出24点.FX2N是FX系列中功能最强、速度最高的微型PLC&#xff0c;内置用户存储器8Kb&#xff0c;可扩展到16K步&#xff0c;最大可扩…

高效Java第六条消除过期的对象引用无意识的对象保持

问题的引出 这段程序有一个“内存泄露”&#xff0c;随着GC活动的增加&#xff0c;或者由于内存占用的不断增加&#xff0c;程序性能降低会逐渐表现出来。在极端的情况下&#xff0c;这种内存泄露会导致磁盘交换&#xff0c;甚至导致程序失败(OutOfMemoryError)&#xff0c;但是…

gentos 执行sh文件_linux定时自动清理日志文件

现有一个应用系统&#xff0c;应用日志记录的内容很多&#xff0c;经常造成存储空间不够&#xff0c;需要手工去删除早期的日志文件来释放空间。应用的日志文件命名如下&#xff0c;固定前后缀加上日期和小时&#xff1a;为了避免手工删除日志&#xff0c;考虑通过写shell脚本来…

java编程思想泛型对混入的详细探讨

混入的概念 把多个类的能力混合在一起产生一个能代表所有混入类的类型的类。 the fundamental concept is that of mixing in capabilities from multiple classes in order to produce a resulting class that represents all the types of the mixins. 混入就是把存在的多…

linux rm 命令删除文件恢复_linux文件处理命令之rm常用方法介绍

命令名称&#xff1a;rm命令英文原意&#xff1a;remove命令所在路径&#xff1a;/bin/rm执行权限&#xff1a;所有用户语法&#xff1a;rm -r [文件或目录] -r 删除目录功能描述&#xff1a;删除文件mv是删除文件的命令,使用时可以指定文件(包括觉得路径/相对路径)的存放位置1…

python中math模块函数_Python常用的一些内建函数和math模块函数

一&#xff1a;Python内建函数 1 #abs取绝对值 2 num -10 3 print(abs(num))4 5 #max 求最大值 6 print(max(6, 9, 2, 12, 8))7 8 #min求最小值 9 print(min(-1, 2, 5, 0, 7))10 11 print(min([1, 3, 7, 0, 2]))12 13 #round 计算一个数值的四舍五入的 14 15 pi 3.14 16 prin…

大家对Java的一些误解

1. System.exit(0)会跳过finally块的执行 System.setSecurityManager(new SecurityManager() { Override public void checkExit(int status) { throw new ThreadDeath(); } }); try { System.exit(0); } finally { System.out.println("In the finally block"); } 这…

python用turtle画皮卡丘_用Python的turtle作画(2)——皮卡丘

from turtle import * # 绘制皮卡丘头部 # 画脸 def face(x, y): begin_fill() penup() # 将海龟移动到指定的坐标 goto(x, y) pendown() # 设置海龟的方向 setheading(40) circle(-150, 69) fillcolor("#FBD624") # 将海龟移动到指定的坐标 penup() goto(53.14, 113…

Java 即将迎来转折点?

嵌入式 Java 我并没有看到这个领域有什么变化。Oracle 完全放弃了在该领域的开发&#xff0c;已经不再提供支持非常流行的 ARM 架构的嵌入式应用程序的二进制文件了。 但是&#xff0c;我预测今年嵌入式应用程序中的 Java 应用将会增长。主要原因有三个&#xff1a; Java ME…

html调用接口_Spring 自调用事务失效,你是怎么解决的?

前言" 相信大家都遇到一种事务失效场景&#xff0c;那就是 Spring 自调用&#xff0c;就是在 Service 方法内&#xff0c;调用另一个加 Transactional 注解的方法&#xff0c;发现事务失效&#xff0c;这时候你是怎么解决的呢&#xff1f; "1 事情回顾那是一个我忘了…

Java中AJAX工作原理是什么

AJAX 指异步JavaScript 及XML(Asynchronous JavaScript And XML)。 传统的Web应用允许用户填写表单(form)&#xff0c;当提交表单时就向Web服务器发送一个请求。服务器接收并处理传来的表单&#xff0c;然后返回一个新的网页。这个做法浪费了许多带宽&#xff0c;因为在前后两个…