面试题答案
一键面试Java垃圾回收机制基本原理
- CMS(Concurrent Mark Sweep)
- 标记 - 清除算法:CMS主要基于标记 - 清除算法。它首先标记出所有需要回收的对象,然后在标记完成后统一回收所有被标记的对象。
- 四个阶段:
- 初始标记(Initial Mark):这个阶段仅仅只是标记一下GC Roots能直接关联到的对象,速度很快,但仍需要暂停应用线程。
- 并发标记(Concurrent Mark):从GC Roots的直接关联对象开始遍历整个对象图的过程,这个过程耗时较长,但不需要暂停应用线程,可以与应用程序并发执行。
- 重新标记(Remark):为了修正并发标记期间因用户程序继续运作而导致标记产生变动的那一部分对象的标记记录,这个阶段的停顿时间通常会比初始标记阶段稍长一些,但远比并发标记的时间短,需要暂停应用线程。
- 并发清除(Concurrent Sweep):清除所有被标记为可以回收的对象,这个阶段也可以和应用程序并发执行。
- G1(Garbage - First)
- 分代与分区:G1将整个Java堆划分为多个大小相等的独立区域(Region),它仍然保留了分代的概念,但分代的区域不是固定的。每个Region都可以扮演Eden、Survivor或者Old的角色。
- 标记 - 整理算法:主要基于标记 - 整理算法,避免了内存碎片的产生。
- 四个步骤:
- 初始标记(Initial Mark):标记GC Roots能直接关联到的对象,需要暂停应用线程。
- 并发标记(Concurrent Mark):从GC Roots开始对堆中对象进行可达性分析,找出存活对象,可与应用程序并发执行。
- 最终标记(Final Mark):为了修正在并发标记期间因用户程序继续运作而导致标记产生变动的那一部分对象的标记记录,需要暂停应用线程。
- 筛选回收(Live Data Counting and Evacuation):首先对各个Region中的回收价值和成本进行排序,根据用户所期望的停顿时间来制定回收计划,可以有计划地避免在整个Java堆中进行全区域的垃圾回收。
根据高并发Web应用场景选择垃圾回收器及参数调整
- 垃圾回收器选择
- CMS:适用于追求低停顿时间的高并发Web应用场景。因为CMS在并发标记和并发清除阶段可以与应用程序并发执行,能减少应用程序的停顿时间,保证Web应用的响应速度。
- G1:对于堆内存较大,并且希望在高并发场景下兼顾停顿时间和吞吐量的Web应用较为合适。G1可以根据用户设定的停顿时间目标来合理地规划垃圾回收,并且它的分代和分区机制使得在回收大内存时更高效。
- 参数调整
- 新生代大小调整依据:
- 经验法则:一般来说,新生代大小应该在整个堆大小的1/3到1/4之间。在高并发Web应用中,如果对象的创建和销毁非常频繁,适当增大新生代可以减少对象进入老年代的频率,从而减少老年代垃圾回收的压力。可以通过
-Xmn
参数来设置新生代大小。 - 监控分析:通过工具(如JVM自带的监控工具、VisualVM等)观察对象的晋升情况。如果发现对象频繁地从新生代晋升到老年代,说明新生代可能过小;如果新生代长期处于空闲状态,说明新生代可能过大。
- 经验法则:一般来说,新生代大小应该在整个堆大小的1/3到1/4之间。在高并发Web应用中,如果对象的创建和销毁非常频繁,适当增大新生代可以减少对象进入老年代的频率,从而减少老年代垃圾回收的压力。可以通过
- 老年代大小调整依据:
- 根据应用特性:如果应用中存在大量生命周期较长的对象,老年代需要分配足够的空间。老年代大小可以通过
-Xmx
减去-Xmn
来间接调整(因为-Xmx
是整个堆大小,-Xmn
是新生代大小)。 - Full GC频率:通过监控Full GC的频率,如果Full GC过于频繁,说明老年代可能过小,需要适当增大;如果老年代空间长期有较大空闲,说明老年代可能过大,可以适当减小。
- 根据应用特性:如果应用中存在大量生命周期较长的对象,老年代需要分配足够的空间。老年代大小可以通过
- 其他参数调整:
- CMS相关参数:
-XX:CMSInitiatingOccupancyFraction
:设置CMS在老年代空间占用率达到多少时开始垃圾回收。在高并发Web应用中,可根据实际情况适当调整,一般默认值是68%,如果应用中对象晋升到老年代的速度较快,可以适当降低这个值,提前触发CMS垃圾回收,避免老年代空间耗尽导致Full GC。-XX:+UseCMSCompactAtFullCollection
:在Full GC后对老年代进行压缩整理,避免产生内存碎片,但会增加停顿时间。可根据实际情况决定是否开启。
- G1相关参数:
-XX:MaxGCPauseMillis
:设置G1的最大停顿时间目标,G1会尽力满足这个目标。在高并发Web应用中,可根据应用对响应时间的要求来设置这个值,例如设置为100毫秒。-XX:G1HeapRegionSize
:设置G1中每个Region的大小,取值范围是1MB到32MB,并且应为2的幂次方。根据堆大小合理设置,一般堆越大,RegionSize也应设置得越大。
- CMS相关参数:
- 新生代大小调整依据: