学习该部分的知识,我的初衷只是为了学习ThrealLocal,结果却被迫补课。后来了解到,这部分知识在面试中出现的频率还比较高,所以就单独写一篇博客,记录记录,也希望对你有帮助

文章目录

  • 1、四种引用类型
  • 2、四种类型的测试
    • 2.1、强引用 new
    • 2.2、软引用 SoftReference
    • 2.3、弱引用 WeakReference
    • 2.4、虚引用 PhantomReference
  • 3、总结

1、四种引用类型

  1. 强引用:最普通的引用 Object o = new Object()
  2. 软引用:垃圾回收器, 内存不够的时候回收 (缓存)
  3. 弱引用:垃圾回收器看见就会回收 (防止内存泄漏)
  4. 虚引用:垃圾回收器看见二话不说就回收,跟没有一样 (管理堆外内存) DirectByteBuffer -> 应用到NIO Netty

2、四种类型的测试

finalize()方法:当对象被回收时, finalize()方法会被调用, 但是不推荐使用去回收一些资源,因为不知道他什么时候会被调用, 有时候不一定会调用

public class Gc {@Override//用于我们显式的调用gc方法以后,测试打印结果protected void finalize() throws Throwable {System.out.println("finalize");}
}

2.1、强引用 new

正常引用,但没有人指向的时候就会被回收.

测试代码:

public class RefStypeTest01 {public static void main(String[] args) throws IOException {Gc gc = new Gc();//第一次执行gc,由于我们的gc对象存在强引用,所以不会被垃圾清理System.gc();System.out.println("--");gc = null;//由于我们将gc对象赋值为null,所以我们会打印相应的结果System.gc();System.in.read();}
}

执行结果:

--
finalize

2.2、软引用 SoftReference

内存不够的时候回收

我们将我们的堆内存修改为19M

测试代码:

package pers.mobian.ThreadLocal;import java.io.IOException;
import java.lang.ref.SoftReference;public class RefStypeTest01 {public static void main(String[] args) throws IOException {//设置我们的软引用的空间 10MSoftReference<byte[]> softReference = new SoftReference<>(new byte[1024 * 1024 * 10]);//打印我们的对象信息System.out.println(softReference.get());//gc回收System.gc();try {Thread.sleep(500);} catch (InterruptedException e) {e.printStackTrace();}System.out.println(softReference.get());//再分配一个数组,由于heap内存放不下, 这个时候系统会回收一次, 如果还是不够,就会回收软引用byte[] bytes = new byte[1024 * 1024 * 10];System.out.println(softReference.get());}
}

执行结果:

[B@880ec60
[B@880ec60
null

2.3、弱引用 WeakReference

使用GC后就会被回收

测试代码:

public class RefStypeTest02 {public static void main(String[] args) throws IOException {WeakReference<Gc> weakReference = new WeakReference<>(new Gc());//打印还没有被回收前的情况System.out.println(weakReference.get());//使用gc回收System.gc();//再次打印被回收以后的情况System.out.println(weakReference.get());}
}

执行结果:

pers.mobian.ThreadLocal.Gc@3f3afe78
null
finalize

2.4、虚引用 PhantomReference

JVM无法访问直接清理

测试代码:

public class RefStypeTest03 {private static final List<Object> LIST = new LinkedList<>();private static final ReferenceQueue QUEUE = new ReferenceQueue();public static void main(String[] args) throws IOException {//实例化我们的虚引用PhantomReference<Gc> phantomReference = new PhantomReference<>(new Gc(), QUEUE);new Thread(() -> {while (true) {LIST.add(new byte[1024 * 1024]);//我们不断地添加数据,但是却拿不到值,因为虚引用的内容在JVM外面System.out.println(phantomReference.get());}}).start();new Thread(() -> {while (true) {//添加一个存储信息的QueueReference<? extends Gc> poll = QUEUE.poll();//当该判断成立时,说明poll队列中含有了我们的对应的清理堆外内存的信息if (poll != null) {System.out.println("-----虚引用对象被JVm回收了--------" + poll);return;}}}).start();}
}

执行结果:

...
null
null//加满我们的堆内存后,才会出发我们的GC,继而向Queue里面添加数据
-----虚引用对象被JVm回收了--------java.lang.ref.PhantomReference@76cbab9f
null
null
null
...

总结:我们传统的数据交换方式,比如获取网络上(BIO、NIO)的数据。我们在网卡这一步首先将数据加载到内存,再将内存终得数据复制到JVM里面,然后再复制到堆里面。这样的十分的浪费资源。于是就出现了我们的虚引用,它直接由OS管理。当我们的不需要使用该数据以后,由于该数据所在的空间是在JVM外面,JVM无法直接处理,于是我们就在堆内存的引用里面添加了一个Queue队列,Queue用来存储信息,当我们不需要使用虚引用的数据时,就会向Queue队列里面添加信息,当Queue检测到有对应地数据时,就会去进行相应的清理堆外内存的操作。继而解决了GC回收不了数据信息,引发的内存溢出。


3、总结

强引用:正常的使用方式。

软引用:内存不够的时候,进行清理。可用于网络上的

弱引用:没有引用时遇到GC直接进行清理。在我们的ThreadLocalMap中就使用了该方式

虚引用:无法获取到对应的值,向Queue队列中添加数据来间接清理。主要是为了增强数据的传输效率

Java的强、软、弱、虚四种引用类型相关推荐

  1. JVM的四种引用:强,软,弱,虚(与gc有关)

    JVM的四种引用 强 软 弱 虚 强 gc时不回收 软 软引用对象在gc时,在内存溢出前,会回收; 弱 弱引用对象在gc时,不论内存使用情况都会回收; 虚 虚引用对象在gc后,会发送一条通知给 Ref ...

  2. Java 四种引用类型:强引用、软引用、弱引用、虚引用

    以前学习强软弱虚引用的时候,只是走马观花看看博客,并没有自己写代码去实践.去证明,导致每次看完后,过不了多久就忘了,后来下定决心,一定要自己敲敲代码,这样才能让印象更加深刻,古人云:纸上得来终觉浅,绝 ...

  3. JAVA的四种引用类型的作用——强引用、软引用、弱引用、虚引用

    Java四种引用类型,按照引用类型的强弱顺序分别是 强引用 软引用 弱引用 虚引用 背景:我们希望有这样一种场景像缓存一样, 即:在内存还足够时,希望能够保留这些对象,当内存不够时,则删除这些对象(当 ...

  4. Java若_【JAVA基础】JAVA四种引用(强软若虚)

    java中有四种引用类型,分别是 强引用 强引用也就是我们通常认为的java中的中的引用关系 通过new创建一个对象,然后赋值给一个变量,这个时候这个变量指向堆中地址的引用就是一个强引用 他收到JVM ...

  5. 四种引用类型(强引用、软引用、弱引用、虚引用)的简单介绍

    四种引用类型 JDK1.2 之前,一个对象只有"已被引用"和"未被引用"两种状态,这将无法描述某些特殊情况下的对象,比如,当内存充足时需要保留,而内存紧张时才需 ...

  6. 多线程与高并发(五):强软弱虚四种引用以及ThreadLocal的原理与源码

    上节回顾 AQS(CLH的变种) 因为新加进来的节点要查看前面的节点的状态,所以使用的是双向链表. AQS的底层是 CAS + Volitile,用CAS替代了锁整个链表的操作. 公平锁:上来先排队 ...

  7. 通过强弱软虚四种引用进一步了解垃圾回收机制

    在Java对象里,有强弱软虚四种引用,它们都和垃圾回收流程密切相关,在项目里,我们可以通过合理地使用不同类型的引用来优化代码的内存使用性能. 指向通过new得到的内存空间的引用叫强引用.比如有Stri ...

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

    点击蓝字 关注我们 点击上方"方志朋",选择"置顶或者星标" 你的关注意义重大! 01 概述 在Java中提供了四个级别的引用:强引用,软引用,弱引用和虚引用. ...

  9. java object 引用类型_java中的四种引用类型

    java中的四种引用类型 一.强引用 强引用是最常见的,把一个对象赋给一个引用变量,这个引用变量就是一个强引用.当一个对象被强引用变量引用时,他处于可达状态,它是不会被GC回收的,即使该对象以后永远不 ...

  10. java ref 应用类型_Java中的四种引用类型比较

    1.引用的概念 引用这个概念是与JAVA虚拟机的垃圾回收有关的,不同的引用类型对应不同的垃圾回收策略或时机. 垃圾收集可能是大家感到难于理解的较难的概念之一,因为它并不能总是毫无遗漏地解决Java运行 ...

最新文章

  1. gdb相关(栈和寄存器)
  2. linux shell 算术运算{expr、bc、dc、(( ))和[ ]}
  3. ASP.NET MVC- Upload File的例子
  4. Linux中的组合键
  5. Spring4.x学习(1)
  6. 美团云、苏宁云相继停止运营,公有云市场大洗牌
  7. redis cluster 分布式锁_Redis的分布式锁的实现原理
  8. 一份清单:所有可以放进head标签的元素
  9. Git(10):删除远端仓库中多余文件(**.iml/target文件)
  10. FFmpeg开发(1)从mp4中提取aac音频
  11. 挖金矿问题java课程设计_Win32 挖金矿游戏源代码
  12. \u5168\u56fd\u7f8e\u5bb9\u5927\u592b数据采集数据(\u82b1\u5bb9\u7f51 huaroo 公开数据),爬虫120例之26例
  13. 原来在Android中请求权限也可以有这么棒的用户体验(转自郭霖)
  14. 【阅读笔记】Deep Mutual Learning
  15. 独立站卖家如何利用Google广告引流
  16. 国内三大B2C网站首页的信息架构【收集整理,本人非原作者】
  17. 平行世界真的存在吗?镜像宇宙的三个科学奥秘
  18. 软件工程师职业道德规范_看一下三个职业道德规范的最新更新
  19. 什么是函数?怎么了解函数?为什么需要函数呢?我来给你解答(上)
  20. 工业计算机检验标准,企业标准规范工业控制计算机检验标准.doc

热门文章

  1. BZOJ2160 拉拉队排练
  2. 高德地图只显示某个省份
  3. 南极沉船_世界上一些神秘的沉船,都成了仿佛被世界遗弃的盛景
  4. python提取百度首页链接_python获取百度热榜链接的实例方法
  5. microsoft html help workshop_云话科技 | 奥比中光Workshop技术研讨线上沙龙
  6. 微博中微服务缓存_微服务实践分享(5)缓存中心
  7. oracle安装5.1,5.1 Oracle RAC的安装(5)
  8. Spring框架的本质:1Spring框架的起源
  9. (3)fastjson带有转义字符的数据格式处理
  10. 编程语言的动态性(Dart和OC对比)