JVM垃圾回收原理:标记回收对象,四种引用,垃圾收集算法,垃圾收集器

本文介绍了JVM垃圾回收的基本原理,包括标记回收对象的两种方法——引用计数法和可达性分析,详细讲解了四种引用类型:强引用、软引用、弱引用和虚引用。此外,还阐述了常见的垃圾收集算法,如标记-清除、复制、标记-整理和分代收集,并探讨了不同垃圾收集器,如Serial、Parallel、CMS和G1的特点与应用场景。
摘要由CSDN通过智能技术生成

本文主要为《深入理解Java虚拟机》第三章的读书记录笔记,同时伴有一些网络上资料的总结。

1. 标记回收对象-对象已死?

Java堆是JVM主要的内存管理区域,里面存放着大量的对象实例和数组。在垃圾回收算法和垃圾收集器之前,首先要做的就是判断哪些对象已经“死去”,需要进行回收即不可能再被任何途径使用的对象。

1.1 引用计数法

引用计数法是这样:给对象中添加一个引用计数器,每当有一个地方使用它时,计数器值就加1。当引用失效时,计数器就减1。任何时刻计数器为0的对象就是不可能再被使用的。

现在主流的Java虚拟机都没有使用引用计数法,最主要的原因就是它很难解决对象之间互相循环引用的问题

1.2 可达性分析

可达性分析的基本思路:通过一系列称为"GC Roots"的对象作为起点,从这些节点开始向下搜索,如果从GC Roots到一个对象不可达,则证明此对象是不可用的,如下图所示。

 

 

Java语言中,可作为GC Roots的对象包括下面几种:

  1. 虚拟机栈(栈帧中的本地变量表)中引用的对象
  2. 本地方法栈JNI(即一般说的Native方法)引用的对象
  3. 方法区中类静态常量引用的对象
  4. 方法区中常量引用的对象

对于Java程序而言,对象基本都位于堆内存中,简单来说GC Roots就是有被堆外区域引用的对象。

2. 四种引用

在JDK 1.2以前的版本中,若一个对象不被任何变量引用,那么程序就无法再使用这个对象。也就是说,只有对象处于(reachable)可达状态,程序才能使用它。

从JDK 1.2版本开始,对象的引用被划分为4种级别,从而使程序能更加灵活地控制对象的生命周期。这4种级别由高到低依次为:强引用软引用弱引用虚引用

2.1 强引用(StrongReference)

强引用是使用最普遍的引用,如下的方式就是强引用:

    Object strongReference = new Object();
复制代码
  1. 如果一个对象具有强引用,那垃圾回收器绝不会回收它。直到强引用的对象不使用或者超出对象的生命周期范围。则GC认为该对象不存在引用,这时候就可以回收这个对象。
  2. 当内存不足时,JVM宁愿抛出OutOfMemoryError的错误,使程序异常终止,也不会靠随意回收具有强引用对象来解决内存不足的问题。

举例来说,

  1. 如下图在一个方法内部具有一个强引用,这个引用保存在虚拟栈的栈帧中,而真正的引用内容Object则保存在Java堆中。当这个方法运行完成后,退出方法栈。这个对象不再被GC Roots可达,那么这个对象在下次GC时就会被回收。
    public void test() {
        Object strongReference = new Object();
        // 省略其他操作
    }
复制代码
  1. 如下图一个类的静态变量需要一个强引用,这个引用保存在方法区中,而真正的引用内容Object则保存在Java堆中。当将这个引用手动制空strongReference = null后。这个对象不再被GC Roots可达,那么这个对象在下次GC时就会被回收。
class Obj {
    pulic static Object strongReference = new Object();
}
复制代码

2.2 软引用(SoftReference)

如果对象具有软引用,则

  1. 内存空间充足时,垃圾回收器不会回收
  2. 内存空间不足时,就会尝试回收这些对象。只要垃圾回收器没有回收它,该对象就可以被程序使用
    // 强引用
    String strongReference = new String("abc");
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值