评估垃圾回收器的性能指标
- 吞吐量:运行用户代码的时间占总运行时间(程序运行时间+内存回收的时间)的比例
- 暂停时间:执行垃圾收集时,程序的工作线程被暂停的时间
- 内存占用:java堆区所占的内存大小
注重吞吐量:
注重低延迟:
暂停时间:让用户线程停止,让GC执行的状态
7种垃圾回收器的概述
7款经典垃圾回收器与垃圾分代之间的关系(分代收集算法)
因为以上关系,所以需要不同的垃圾回收器组合使用
jdk1.7 默认垃圾收集器Parallel Scavenge(新生代)+Parallel Old(老年代)
jdk1.8 默认垃圾收集器Parallel Scavenge(新生代)+Parallel Old(老年代)
jdk1.9 默认垃圾收集器G1
Serial收集器
Serial(串行)回收器:串行回收 单线程的垃圾回收器
Serial收集器采用复制的算法(适用于新生代),串行回收和"stop-the-world"机制的方式执行内存回收
Serial Old是运行在老年代的垃圾回收器(标记压缩算法)
如果设置新生代垃圾回收器为Serial,老年代默认为Serial Old垃圾回收器
适用于单核的机器(如嵌入式等等)
ParNew回收器:并行回收 主要用于新生代垃圾回收
对于新生代,回收次数频繁,使用并行方式高效
对于老年代,回收次数少,使用串行方式节约资源(cpu并行需要切换线程,串行可以省去切换线程的资源)
Paralle回收器:吞吐量优先
Parallel Old收集器采用了标记-压缩算法,但同样也是基于并行回收和"stop-the-world"机制
- 在程序吞吐量优先的应用场景种,Paralle收集器和和Parallel Old收集器的组合,在Server模式下的内存回收性能很不错
- 在java8,是默认垃圾回收器
- 适用于后台运算而不需要太多交互的任务
CMS回收器:低延迟 并发收集 使用标记-清除算法 作为老年代的收集器
**初始标记:**仅仅实质时标记出GCRoots能直接关联到的对象
**并发标记:**从GCRoots的之间关联对象开始遍历整个对象图的过程
**重新标记:**修正并发标记期间,因用户程序继续运行而导致标记发生变动的那一部分的标记记录
并发清除:清理删除标记阶段判断已经死亡的对象,释放内存空间
由于最耗费时间的并发标记与并发清除阶段都不需要STW,所以整体是低停顿的
由于在垃圾收集阶段用户线程没有中断,所以在CMS回收阶段,还应该保证有足够的空间供程序用户线程和GC线程使用,因此,CMS收集器不能像其它收集器那样等到老年代几乎填满了再进行回收,而是当堆内存使用率达到某一阈值时,便开始进行回收。如果剩余内存不够启动CMS使用,就启动Serial Old收集器来重新进行老年代的垃圾收集
CMS的优点:
- 并发收集
- 低延迟
CMS的缺点: - 会产生内存碎片
- CMS收集器对CPU资源非常敏感
- CMS收集器无法处理浮动垃圾
G1回收器:区域化分代式,并行收集器
jdk9的默认GC
- 因为GC是一个并行收集器,它把对内存分割为很多不相关的区域。使用不同的Region来表示Eden,幸存者1区,幸存者2区,老年代等等
- G1GC有计划地避免在整个Java堆中进行全区域的垃圾收集。GI跟踪各个Reiogion里面的垃圾堆积的价值大小(回收所获得的空间大小以及回收所需时间的经验值),在后台维护一个优先列表,每次根据允许的收集时间,优先回收价值最大的Region。
- 由于这种方式的侧重点在于回收垃圾最大量的区间(Region),所以我们给GI一个名字:垃圾优先(GarbageFirst)
G1的特点
- 并行与并发
- 并行性:G1在回收期间,可以有多个GC线程同时工作,有效利用多核计算能力。此时用户线程
- 并发性:GI拥有与应用程序交替执行的能力,部分工作可以和应用程序同时执行,因此,一般来说,不会在整个回收阶段- 发生完全阻塞应用程序的情况
- 分代收集
- 从分代上看,G1依然属于分代型垃圾回收器,它会区分年轻代和老年代,年轻代依然有Eden区和Survivor区。但从堆的结构上看,它不要求整个Eden区、年轻代或者老年代都是连续的,也不再坚持固定大小和固定数量。
- 将堆空间分为若干个区域(Region),这些区域中包含了逻辑上的年轻代和老年代。
- 和之前的各类回收器不同,它同时兼顾年轻代和老年代。对比其他回收器,或者工作在年轻代,或者工作在老年代:
- 空间整合
- “标记一清除”算法、内存碎片、若干次后进行一次碎片整理
- 内存的回收是以region作为基本单位的,Region之间是复制算法,但整体上实际可看作标记-压缩算法,两种算法都可以避免内存碎片
G1回收器过程
幸存者区不会主动触发youngGC,都是伊甸园区触发youngGC,幸存者区被动的被回收
并发标记阶段 主要针对老年代
混合回收:
记忆集
G1对每个region都维护了一个记忆集,避免在新生代回收时要遍历老年区的region