MST

星途 面试题库

面试题:Java虚拟机垃圾回收器调优

给定一个高并发、低延迟要求的Java应用,默认的垃圾回收器无法满足性能需求。请分析常见垃圾回收器(如CMS、G1)的特点,并阐述如何根据应用场景选择合适的垃圾回收器并进行相应调优,以达到低延迟和高吞吐量的平衡。
18.9万 热度难度
编程语言Java

知识考点

AI 面试

面试题答案

一键面试

CMS垃圾回收器特点

  1. 并发收集:CMS(Concurrent Mark Sweep)垃圾回收器以获取最短回收停顿时间为目标,它在垃圾回收过程中,尽可能地与应用程序并发执行,减少应用程序的停顿时间。
  2. 标记 - 清除算法:采用标记 - 清除算法,先标记出所有需要回收的对象,然后直接清除这些对象。这种算法避免了在垃圾回收过程中进行大量的对象移动,减少了停顿时间。
  3. 停顿时间短:适用于对响应时间要求高的应用程序,在老年代垃圾回收时能有效降低停顿时间,提升用户体验。
  4. 缺点:会产生内存碎片,随着时间推移,可能导致无法分配大对象,从而触发Full GC;而且并发阶段会占用部分CPU资源,影响应用程序的吞吐量。

G1垃圾回收器特点

  1. 区域化分代:G1(Garbage - First)将堆内存划分为多个大小相等的Region,这些Region可以动态地被划分成不同的代,打破了传统分代收集的固定区域划分模式。
  2. 优先回收垃圾最多区域:G1会根据每个Region中垃圾的多少,优先回收垃圾最多的Region,即Garbage - First。这样可以在有限的时间内尽可能多地回收垃圾,提高回收效率。
  3. 可预测的停顿时间:通过参数可以设置期望的停顿时间,G1会尽力满足这个时间要求,在高并发场景下能更好地控制应用程序的停顿时间。
  4. 整体采用标记 - 整理算法:避免了内存碎片的产生,在回收完成后,会对堆内存进行整理,使内存空间更加紧凑。

根据应用场景选择垃圾回收器

  1. 高并发、低延迟且吞吐量要求相对不那么极致:如果应用对响应时间极为敏感,对吞吐量有一定容忍度,CMS可能是一个不错的选择。例如Web应用、实时交互系统等,用户对响应时间感知明显。但要注意CMS产生的内存碎片问题,需要合理设置堆内存大小及相关参数来尽量避免因碎片导致的Full GC。
  2. 高并发、低延迟且对吞吐量有较高要求:对于既需要低延迟又希望有较高吞吐量的场景,G1更合适。如大规模电商系统、金融交易系统等,在保证响应速度的同时,也需要系统能处理大量的请求。G1通过区域划分和优先回收垃圾多的区域,能在满足低延迟要求的同时,保持较好的吞吐量。

垃圾回收器调优

  1. CMS调优
    • 设置堆大小:根据应用程序的实际需求,合理设置堆的初始大小(-Xms)和最大大小(-Xmx),避免频繁的Full GC。
    • 调整并发线程数:通过-XX:ConcGCThreads参数调整并发垃圾回收线程数,一般为CPU核心数的1/4到1/2。并发线程数过少可能导致垃圾回收时间过长,过多则会占用过多CPU资源影响应用程序。
    • 设置CMSInitiatingOccupancyFraction:这个参数用于设置CMS垃圾回收器在老年代空间占用达到多少比例时开始启动并发回收周期。合理设置该值可以避免老年代空间耗尽才触发回收,一般可以设置为70% - 80%。如果设置过低,会导致频繁触发CMS回收,影响吞吐量;设置过高,可能导致老年代空间不足引发Full GC。
  2. G1调优
    • 设置目标停顿时间:通过-XX:MaxGCPauseMillis参数设置期望的最大停顿时间,G1会尽量在这个时间内完成垃圾回收。但要注意设置的值不能过小,否则可能导致回收效率低下,吞吐量降低。
    • 调整堆大小:与CMS类似,合理设置堆的初始大小(-Xms)和最大大小(-Xmx),并且根据应用程序的对象分配模式,调整新生代和老年代的比例。G1可以通过-XX:G1NewSizePercent-XX:G1MaxNewSizePercent参数来控制新生代大小的比例范围。
    • 设置并发线程数:使用-XX:ConcGCThreads参数设置并发垃圾回收线程数,与CMS不同的是,G1会根据CPU核心数自动计算默认的并发线程数,但在某些情况下,也可以手动调整以优化性能。