JVM垃圾回收——五种引用

简介: 如果在垃圾回收时发现内存不足,在回收软引用所指向的对象时,软引用本身不会被清理

image.png


image.png


强引用


只有GC Root都不引用该对象时,才会回收强引用对象


  • 如上图B、C对象都不引用A1对象时,A1对象才会被回收


软引用


当GC Root指向软引用对象时,在内存不足时,会回收软引用所引用的对象


  • 如上图如果B对象不再引用A2对象且内存不足时,软引用所引用的A2对象就会被回收


软引用的使用


public class Demo1 {
  public static void main(String[] args) {
    final int _4M = 4*1024*1024;
    //list中是软引用,软引用当中是byte数组
        // List 对 SoftReference 是强引用,而 SoftReference 对 byte[] 是软引用
    List<SoftReference<byte[]>> list = new ArrayList<>();
    SoftReference<byte[]> ref= new SoftReference<>(new byte[_4M]);
        list.add(ref);
  }
}


如果在垃圾回收时发现内存不足,在回收软引用所指向的对象时,软引用本身不会被清理


如果想要清理软引用,需要使用引用队列


public class Demo1 {
  public static void main(String[] args) {
    final int _4M = 4*1024*1024;
        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[_4M], 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();
    }
  }
}


**大概思路为:**查看引用队列中有无软引用,如果有,则将该软引用从存放它的集合中移除(这里为一个list集合)


弱引用


只有弱引用引用该对象时,在垃圾回收时,无论内存是否充足,都会回收弱引用所引用的对象


  • 如上图如果B对象不再引用 A3 对象,则 A3 对象会被回收


弱引用的使用和软引用类似,只是将 SoftReference 换为了 WeakReference


虚引用


当虚引用对象所引用的对象被回收以后,虚引用对象就会被放入引用队列中,调用虚引用的方法


  • 虚引用的一个体现是释放直接内存所分配的内存,当引用的对象ByteBuffer被垃圾回收以后,虚引用对象Cleaner就会被放入引用队列中,然后调用Cleaner的clean方法来释放直接内存
  • 如上图,B对象不再引用ByteBuffer对象,ByteBuffer就会被回收。但是直接内存中的内存还未被回收。这时需要将虚引用对象Cleaner放入引用队列中,然后调用它的clean方法来释放直接内存


终结器引用


所有的类都继承自Object类,Object类有一个finalize方法。当某个对象不再被其他的对象所引用时,会先将终结器引用对象放入引用队列中,然后根据终结器引用对象找到它所引用的对象,然后调用该对象的finalize方法。调用以后,该对象就可以被垃圾回收了


  • 如上图,B对象不再引用A4对象。这是终结器对象就会被放入引用队列中,引用队列会根据它,找到它所引用的对象。然后调用被引用对象的 finalize 方法。调用以后,该对象就可以被垃圾回收了。我们是不推荐去使用finalize 方法的,因为其效率太低了。


引用队列


  • 软引用和弱引用可以配合引用队列
  • 在软引用和弱引用所引用的对象被回收以后,会将这些引用放入引用队列中,方便一起回收这些软/弱引用对象
  • 虚引用和终结器引用必须配合引用队列
  • 虚引用和终结器引用在使用时会关联一个引用队列
目录
相关文章
|
15天前
|
存储 算法 Oracle
极致八股文之JVM垃圾回收器G1&ZGC详解
本文作者分享了一些垃圾回收器的执行过程,希望给大家参考。
|
2月前
|
存储 算法 Java
Java面试题:深入探究Java内存模型与垃圾回收机制,解释JVM中堆内存和栈内存的主要区别,谈谈对Java垃圾回收机制的理解,Java中的内存泄漏及其产生原因,如何检测和解决内存泄漏问题
Java面试题:深入探究Java内存模型与垃圾回收机制,解释JVM中堆内存和栈内存的主要区别,谈谈对Java垃圾回收机制的理解,Java中的内存泄漏及其产生原因,如何检测和解决内存泄漏问题
46 0
|
2月前
|
存储 算法 安全
Java面试题:Java内存模型及相关知识点深度解析,Java虚拟机的内存结构及各部分作用,详解Java的垃圾回收机制,谈谈你对Java内存溢出(OutOfMemoryError)的理解?
Java面试题:Java内存模型及相关知识点深度解析,Java虚拟机的内存结构及各部分作用,详解Java的垃圾回收机制,谈谈你对Java内存溢出(OutOfMemoryError)的理解?
45 0
|
2月前
|
Java
Jinfo 查看 jvm 配置及使用 Jstat 查看堆内存使用与垃圾回收
Jinfo 查看 jvm 配置及使用 Jstat 查看堆内存使用与垃圾回收
37 5
|
2月前
|
存储 算法 Java
JVM 垃圾回收算法与垃圾回收器
JVM 垃圾回收算法与垃圾回收器
34 3
|
26天前
|
算法 Java 应用服务中间件
探索JVM垃圾回收算法:选择适合你应用的最佳GC策略
探索JVM垃圾回收算法:选择适合你应用的最佳GC策略
|
2月前
|
监控 Java 运维
开发与运维收集问题之jstat命令查看JVM垃圾回收情况如何解决
开发与运维收集问题之jstat命令查看JVM垃圾回收情况如何解决
20 1
|
2月前
|
弹性计算 运维 Java
Serverless 应用引擎使用问题之JVM进行垃圾回收时重启,该如何解决
阿里云Serverless 应用引擎(SAE)提供了完整的微服务应用生命周期管理能力,包括应用部署、服务治理、开发运维、资源管理等功能,并通过扩展功能支持多环境管理、API Gateway、事件驱动等高级应用场景,帮助企业快速构建、部署、运维和扩展微服务架构,实现Serverless化的应用部署与运维模式。以下是对SAE产品使用合集的概述,包括应用管理、服务治理、开发运维、资源管理等方面。
|
3月前
|
存储 算法 Java
技术笔记:JVM的垃圾回收机制总结(垃圾收集、回收算法、垃圾回收器)
技术笔记:JVM的垃圾回收机制总结(垃圾收集、回收算法、垃圾回收器)
38 1
|
2月前
|
存储 监控 算法
探索Java虚拟机:深入理解JVM内存模型和垃圾回收机制
在Java的世界中,JVM是核心所在,它不仅承载着代码的运行,还管理着内存资源。本文将带你深入了解JVM的内存模型和垃圾回收机制,通过具体数据与案例分析,揭示它们对Java应用性能的影响,并探讨如何优化JVM配置以提升效率。