Java教程

JVM学习笔记——GC算法

本文主要是介绍JVM学习笔记——GC算法,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

GC 算法

  GC 即 Garbage Collection 垃圾回收。JVM 中的 GC 99%发生在堆中,而 Java 堆中采用的垃圾回收机制为分代收集算法。即将堆分为新生代和老年代,根据不同的区域使用不同的垃圾回收算法。

 

1. 确认垃圾的算法

1.1 引用计数法

  给每个对象设置一个引用计数器,每有一个地方引用此对象时,计数器 +1,引用失效计数器 -1。当对象计数器为0时,将会被垃圾回收。

  引用计数器无法解决循环引用的问题。当AB两个对象都无其他对象引用,且 A 对象引用 B 对象,B 对象也引用 A 对象时,两个对象本应被回收,但计数器都不为0,无法垃圾回收。

  因此主流虚拟机都未采用此算法。

 

1.2 可达性算法(引用链法)

  从一个被视为 GC Roots 的对象开始向下搜索,如果一个对象到 GC Roots 没有任何引用链相连时,说明此对象不可用,可以被垃圾回收。

 

 Java 中可作为 GC Roots 的对象如下:

  • 虚拟机栈中引用的对象

  • 方法区类静态属性引用的对象

  • 方法区常量池引用的对象

  • 本地方法栈 JNI 引用的对象

 

  当一个对象不可达 GC Roots 时,这个对象不会立马被回收,而是处于死缓的阶段,若要真正被回收需要经历两次标记。

  被第一次标记的对象会经历一次筛选,筛选是否有必要进行finalize()方法,对象如果已被虚拟机调用过或认定没必要执行finalize()方法,则立即回收。

  如果需要执行finalize()方法,则把对象放入 F-Queue 队列中,等待Finalize()线程执行,该线程为低优先级,且不被 JVM 承诺执行完毕。GC对 F-Queue 队列中的对象进行二次标记,被标记后等待回收。

 

2. 垃圾回收算法

2.1 标记清除算法 Mark-Sweep

  最基础的垃圾回收算法,分两个阶段,标记,清除。标记所需回收的对象,清除被标记的对象。

  看似简单,但该算法最大的问题在于内存碎片化严重,如果清理后不整理内存,整块内存就会被存活的对象分割成一块块较小的连续空间,当需要创建较大对象时会难以在内存中找到合适的连续空间。

  • 节约空间

  • 需要进行两次扫描,耗时严重

  • 内存碎片化严重

  • 老年代标记清除,标记压缩结合使用

 

2.2 复制算法 Copying

  为了解决标记清除算法内存碎片化的缺陷而被提出。

  按内存容量将内存划分为两块,每次只使用其中一块,当一块内存存满后,将存活的对象复制至另一块,清空当前块内的内存,然后两边互换使用。

  • 算法实现简单,内存效率高,不易产生碎片

  • 使用空间被压缩,浪费了一点空间,如果存活对象增多,算法效率会大大降低

 

2.3 标记整理算法 Mark-Compact

  结合标记清除算法和复制算法被提出。

 

算法思想:

  • 标记死亡对象

  • 将存活对象移动至内存另一端

  • 清除端边界外所有对象

  

 特点:

  • 内存连续,不产生碎片

  • 效率不高,要标记存活对象,整理对象引用地址,效率低于复制算法

  • 老年代标记清除,标记压缩结合使用

这篇关于JVM学习笔记——GC算法的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!