我们再给出软引用对象回收的相关测试代码:
package cn.itcast.jvm.t2;import java.lang.ref.Reference;import java.lang.ref.ReferenceQueue;import java.lang.ref.SoftReference;import java.util.ArrayList;import java.util.List;/** * 演示软引用, 配合引用队列 */public class Demo2_4 {private static final int _4MB = 4 * 1024 * 1024;public static void main(String[] args) {// 这里设置了List , 里面的SoftReference是软引用对象 , 再在里面添加的数据就是软引用对象所引用的A2对象List<SoftReference<byte[]>> list = new ArrayList<>();// 引用队列(类型和引用对象的类型相同即可)ReferenceQueue<byte[]> queue = new ReferenceQueue<>();for (int i = 0; i < 5; i++) {// 关联了引用队列,当软引用所关联的 byte[]被回收时,软引用自己会加入到 queue 中去SoftReference<byte[]> ref = new SoftReference<>(new byte[_4MB], queue);System.out.println(ref.get());list.add(ref);System.out.println(list.size());}// 从队列中获取无用的 软引用对象,并移除Reference<? extends byte[]> poll = queue.poll();while( poll != null) {list.remove(poll);poll = queue.poll();}System.out.println("===========================");for (SoftReference<byte[]> reference : list) {System.out.println(reference.get());}}}/*和之前那此调试相同,前四次正常运行,在第五次时进行了gc清理但是在循环结束之后,我们将软引用对象放入到了引用队列中并进行了清理,所以这时我们的list中前四次软引用对象直接消失我们只能看到list中只有一个对象:[B@330bedb4*/
弱引用上述图片中的A3对象就是弱引用示例
我们下面介绍强弱引用的概念:
- 弱引用不是由根Root直接引用,而是采用一个弱引用对象WeakReference连接
- 当该对象没有被强引用连接,被弱引用连接时在进行Full gc时会被强制回收
- 每次进行老年代的Full gc(后面会讲到Full gc,这里就当作大型垃圾回收)时都会被强制回收
- 我们通常将弱引用对象绑定一个引用队列
- 当该弱引用对象不再连接任何对象时 , 将其放入引用队列 , 引用队列会进行检测 , 检测到弱引用对象就会对其进行垃圾回收
package cn.itcast.jvm.t2;import java.lang.ref.Reference;import java.lang.ref.ReferenceQueue;import java.lang.ref.SoftReference;import java.lang.ref.WeakReference;import java.util.ArrayList;import java.util.List;/** * 演示弱引用 * -Xmx20m -XX:+PrintGCDetails -verbose:gc */public class Demo2_5 {private static final int _4MB = 4 * 1024 * 1024;public static void main(String[] args) {//list --> WeakReference --> byte[]List<WeakReference<byte[]>> list = new ArrayList<>();for (int i = 0; i < 10; i++) {WeakReference<byte[]> ref = new WeakReference<>(new byte[_4MB]);list.add(ref);for (WeakReference<byte[]> w : list) {System.out.print(w.get()+" ");}System.out.println();}System.out.println("循环结束:" + list.size());}}/*这时我们的小型gc(新生代gc)是不会触发弱引用全部删除的(新生代我们后面会讲到)只有当内存全部占满后,触发的Full gc才会导致弱引用的必定回收例如我们在第5,7次新生代发生内存占满,这时触发了新生代的gc,但是只会删除部分WeakReference当我们第9次新生代,老生代内存全部占满后会发生一次Full gc,这时就会引起全部弱引用数据删除,所以我们的数据会变成:nullnullnullnullnullnullnullnullnull[B@330bedb4*/
虚引用上述图片中的ByteBuffer对象就是虚引用示例我们下面介绍虚引用的概念:
- 虚引用实际上就是直接内存的引用,我们内存结构篇所学习的ByteBuffer就是例子
- 系统首先会创建一个虚引用,然后这个虚引用会创建一个ByteBuffer对象,ByteBuffer对象通过unsafe来管理直接内存
- 此外,我们的虚引用必定需要绑定一个引用队列,因为我们的byteBuffer对象是无法控制直接内存的,我们需要检测虚引用来删除
- 首先我们会手动删除或者系统垃圾回收掉ByteBuffer对象
- 这时我们的虚引用和直接内存是不会消失的,但是我们的虚引用会被带到引用队列中
- 虚引用中携带者Cleaner对象,引用队列会一直检测是否有Cleaner对象进入,当检测到时会执行这个Cleaner方法来删除直接内存
- 引用队列中检测Cleaner对象的优先级较高,所以效率相关而言比较快
推荐阅读
- 黑莓q5用安装微信的方法a 用黑莓自带的印象笔记手敲的 看不懂的宝宝们在私聊我吧
- JVM学习笔记——内存结构篇
- 【lwip】08-ARP协议一图笔记及源码实现
- 小米笔记本Pro15增强版评测_小米笔记本Pro15增强版评测表现
- 用一台笔记本电脑如何赚钱(笔记本电脑赚钱的办法)
- 四 【单片机入门】应用层软件开发的单片机学习之路-----ESP32开发板PWM控制电机以及中断的使用
- 笔记本电脑CF中烟雾头怎么调(win10cf新版本烟雾保护头怎么调)
- 笔记本电脑配置高低怎么区分(笔记本电脑看什么配置判断好坏)
- pytorch、paddlepaddle等环境搭建 深度学习环境搭建常用网址、conda/pip命令行整理
- 三十九 Java开发学习----SpringBoot整合mybatis