Skip to content

Latest commit

 

History

History
27 lines (27 loc) · 2.42 KB

GC.md

File metadata and controls

27 lines (27 loc) · 2.42 KB

Java 中垃圾回收机制中如何判断对象需要回收?

“要回收的对象”是指那些不可能再被任何途径使用的对象。那么如何找到这些对象?主要有两个算法:

引用计数法

  • 给对象中添加一个引用计数器,每当一个地方引用这个对象时,计数器值+1;当引用失效时,计数器值-1。任何时刻计数值为0的对象就是不可能再被使用的。
  • 这种算法使用场景很多,不过Java中使用这种算法,因为这种算法很难解决对象之间循环引用的情况。

可达性分析法 å

  • 一系列称为“GC Roots”的对象作为起始点,从这些节点向下搜索,搜索所走过的路径称为引用链,当一个对象到GC Roots没有任何引用链(即GC Roots到对象不可达)时,则证明此对象是不可用的。
  • GCRoots的对象包括下面几种:(1). 虚拟机栈中引用的对象。(2). 方法区中的类静态属性和常量引用的对象。(3). 本地方法栈中JNI(Native方法)引用的对象。

常见的 GC 回收算法有哪些?

1. 标记-清除(Mark-Sweep)算法

  • 标记可达对象,寻找未标记的对象并释放内存。一般单线程工作并需要停止其他操作。
  • 缺点:没有对标记对象进行压缩,导致产生大量碎片,浪费内存。

2. 标记-压缩(Mark-Compact)算法

  • 第一阶段和标记清除相同,第二阶段把标记的对象复制到堆栈新域中以便压缩。
  • 缺点:这种收集方法也需要停止其他的操作。

3. 复制(Copying)算法

  • 收集器将堆栈空间分为两个域,每次仅用一半空间。 JVM生成的对象放在一半的空间中,GC运行时把可达对象复制到另一半,从而压缩堆栈。
  • 特点:该方法适用短生存期的对象,指定大小堆来说每次都需要两倍大小内存,浪费了内存。

4. 增量收集器

  • 把堆栈分为多个域,每次从一个域中收集垃圾。
  • 优点:造成较小的应用程序中断时间(STW),使用户一半不能察觉到垃圾收集器正在工作。

5. 分代收集算法

  • 把堆栈分为2个或者多个域,存放不同寿命的对象-年轻代和老年代
  • 不同的代使用不同的算法:
    • 年轻代:使用复制算法因为每次GC大批对象死去、少量对象存活.
    • 老年代:使用标记清除或者标记压缩,因为对象存活率高、没有额外空间进行分配担保