java中,内存运行时区域中的程序计数器、虚拟机栈、本地方法栈3个区域生命周期随着线程的生存而生存,而堆和方法区被各线程共享,这些占用空间而不被任何对象引用的对象,我们称之为垃圾(Garbage),而垃圾收集器(Garbage Collector)的工作即是通过一些列算法对这些垃圾进行清理。
分代收集算法是基于JVM内存分代模型的一种算法,是目前大部分垃圾收集器都采用的算法,它的核心思想是根据对象存活的生命周期将内存划分为新生代和老年代,老年代的特点是每次垃圾回收时都只有少量的对象被回收,而新生代的特点是每次垃圾回收时都有大量的对象需要被回收,可以根据不同的特点采取适合的回收算法。
以GC Roots为起点向下扫描,扫描所经过的路径称之为引用链,当一个对象不在引用链上,说明该对象不可用。
GC Roots定义:在JAVA语言中,存在虚拟机栈、本地方法栈、方法区、常量池等引用的对象。
垃圾回收是在垃圾定位后的操作行为,常见的垃圾回收算法有:标记-清除、复制算法、标记压缩。
通过根可达算法标记被引用的对象即存活对象,未被标记的则为垃圾对象,然后对其清除。
其特点为:算法相对简单,需要扫描两遍空间(第一次 标记,第二次清除),清理后容易产生碎片。适用于存活对象多的情况(标记多,回收少),多为老年代。
通过根可达算法标记所有存活的对象并将这些对象复制到另一块内存中,然后将之前的内存全部回收。
其特点为:需要一块空的内存去移动复制对象,调整对象的引用,只需扫描一次,清理后不会产生碎片,适用于存活对象少的情况(标记少,回收多),多为新生代。
与标记-清除算法相似,不同的是在清除后再将存活的对象整理压缩在一起。
其特点优化了标记清除算法的碎片,因为需要移动对象,效率较低。
如图所示,图中展示了7种不同分代的收集器,在实际虚拟机中都是搭配使用,以达到最佳效果。
收集器 | 描述 | 算法 |
---|---|---|
Serial | 新生代单线程收集器,标记和清理都是单线程。 | 复制算法 |
Serial Old | 老年代单线程收集器,Serial收集器的老年代版本。 | 标记-整理算法 |
ParNew | 新生代收集器,可以认为是Serial收集器的多线程版本,在多核CPU环境下有着比Serial更好的表现。 | 复制算法 |
Parallel Scavenge | 并行收集器,多个收集器线程同时工作,追求高吞吐量,高效利用CPU。 | 复制算法 |
Parallel Old | Parallel Scavenge收集器的老年代版本,并行收集器,吞吐量优先 | 复制算法 |
CMS | 并发收集器,收集器线程与用户线程同时工作。高并发、低停顿,追求最短GC回收停顿时间,cpu占用比较高,响应时间快,停顿时间短,多核cpu 追求高响应时间的选择 | 三色标记+Incremental Update |
G1 | 并发收集器,不存在分代,适用于不需要实现很高的吞吐量的场景 | 三色标记 +SATB |
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。