JVM垃圾回收器

1 垃圾回收器的位置

JVM垃圾回收器_第1张图片

2 垃圾回收器的基本概念

  什么是垃圾回收器:JVM 为 Java 提供了垃圾回收机制,是一种偏自动的内存管理机制。简单来说,垃圾回收器会自动追踪所有正在使用的对象,并将其余未被使用的对象标记为垃圾,JVM会自动进行垃圾回收,释放内存。

  哪些内存需要回收:不可能再被任何途径所使用的对象,Java中通过可达性分析法来检测对象是否为垃圾,如果不可达,则将对象标记为垃圾,等待 JVM 回收。

3 可达性分析法

3.1原理

  通过一系列称为"GC Roots"的对象作为起始点,从这些节点向下搜索,搜索所走过的路径称为引用链,当GC Roots到对象不可达时证明此对象是不可用的。
  那么如何选取 GCRoots 对象呢?在 Java 语言中,可以作为 GCRoots 的对象包括下面几种:
JVM垃圾回收器_第2张图片

  虚拟机栈(栈帧的局部变量表)中的引用的对象:我们在程序中正常创建一个对象,对象会在堆上开辟一块空间,同时会将这块空间的地址作为引用保存到虚拟机栈中,如果对象生命周期结束了,那么引用就会从虚拟机栈中出栈,因此如果在虚拟机栈中有引用,就说明这个对象还是有用的,这种情况是最常见的;
  全局的静态的对象:也就是使用了 static 关键字,由于虚拟机栈是线程私有的,所以这种对象的引用会保存在共有的方法区中,显然将方法区中的静态引用作为 GC Roots 是必须的;
  常量引用:就是使用了 static final 关键字,由于这种引用初始化之后不会修改,所以方法区常量池里的引用的对象也应该作为 GC Roots;
  Native 方法引用对象:这一种是在使用 JNI 技术时,有时候单纯的 Java 代码并不能满足我们的需求,我们可能需要在 Java 中调用 C 或 C++ 的代码,因此会使用 native 方法,JVM 内存中专门有一块本地方法栈,用来保存这些对象的引用,所以本地方法栈中引用的对象也会被作为 GC Roots。
  上图中,对象 A,B,C,D,E,F 为可达对象;而对象 G,H,I,J,K 为不可达对象,会被标记为垃圾对象,最终被垃圾回收器回收。

3.2 可达性分析的四种引用类型

  由上可知,可达性分析的 GC Roots 均为引用对象,而引用对象有 4 种引用类型:
JVM垃圾回收器_第3张图片

3.2.1 强引用

  定义:强引用就是指在程序代码之中普遍存在的,类似Object obj = new Object()这类的引用,只要强引用还存在,垃圾收集器永远不会回收掉被引用的对象。当内存空间不足,Java 虚拟机宁愿抛出 OutOfMemoryError 错误,使程序异常终止,也不会靠随意回收具有强引用的对象来解决内存不足的问题。
  代码示例:

public class DemoTest {
   
    public static void main(String[] args) {
   
        Object obj = new Object(); // 强引用
    }
}

  在强引用的定义中有这样一句话:“只要强引用还存在,垃圾收集器永远不会回收掉被引用的对象。” 那么有没有办法将强引用消除呢?
  消除强引用示例代码:

public class DemoTest {
   
    public static void main(String[] args) {
   
        Object obj = new Object(

你可能感兴趣的:(Java开发)