Sorry, your browser cannot access this site
This page requires browser support (enable) JavaScript
Learn more >

最近在重新看JVM的内容,这篇文章重新梳理一下垃圾回收中的相关内容。

Java中的垃圾回收(Garbage Collection, GC)指的是回收堆和方法区中不再使用被使用到的对象,即垃圾。

GC中需要考虑的三个主要问题:

  • 什么是垃圾:即哪些对象可以被定义为垃圾
  • 何时回收
  • 如何回收

本文将针对上述三个问题一一解答。

什么是垃圾?

这里就涉及到两种判断对象是否存活的算法:

引用计数法

给每个对象添加一个计数器,当它被某些地方引用是,计数器加一,引用失效时,计数器减一,那些计数器为零的对象就是垃圾了。这种方法的一个关键问题是会出现循环引用,即对象A里面的成员引用了对象B,而对象B里面的成员又引用了对象A

可达性分析算法

通过一系列成为“GC Roots”的对象作为起点,从这些节点开始向下搜索,搜索走过的路径叫做引用链,当一个对象到GC Roots没有任何引用链相连时,则说明这个对象不可用。

那么问题来了,什么是GC Root,哪些对象可以成为GC Root?

在Java中,可以作为GC Root的对象包括以下几种:

  • 虚拟机栈中引用的对象
  • 方法区中类静态属性引用的对象
  • 方法区中常量引用的对象
  • 本地方法栈中JNI引用的对象

其实上面的GC Root也是有规律可循的,分为两种:一种是栈中引用的对象(包括虚拟机栈和本地方法栈),一种则是方法区中的静态属性和常量引用的对象

如何回收

标记清除算法

内存碎片过多

复制算法

通过折半内存空间来避免出现内存碎片

标记整理算法

内存变动频繁,需要整理所有存活对象的内存地址

分代收集算法

将堆空间分为新生代和老年代,新生代又分为一个比较大的Eden区和两个比较小的survivor区。

两个survivor区起的就是一个缓冲的作用。

新生代98%的对象朝生夕死,采用复制算法。

老年代采用标记-整理算法。

何时回收

常见的垃圾收集器:

评论