版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
JVMGC高频面试题及详细答案(实战向)一、基础概念类(初级必问)1、什么是GC?为什么需要GC?GC就是垃圾回收,是JVM自动管理内存的机制。程序运行过程中会不断创建对象,用完的对象如果不清理,会一直占用堆内存,时间久了就会导致内存溢出、内存泄漏。早期C/C++需要开发者手动申请和释放内存,很容易出现忘记释放、重复释放的问题。Java通过GC自动识别无用对象、回收占用内存,让开发者不用手动管理堆内存,提升开发效率同时降低内存出错概率。简单说,GC的核心作用就是清理无效对象、释放堆内存、保证内存可用、避免OOM。2、什么样的对象会被判定为垃圾对象?JVM中没有任何有效引用指向的对象,就是垃圾对象,主要通过两种方式判定:1)引用计数法给每个对象添加引用计数器,有新引用指向就+1,引用失效就-1,计数器为0即为垃圾。优点是简单高效、实时性好;最大缺陷是无法解决循环引用问题,所以主流JVM基本不再单独使用。2)可达性分析法(主流方式)以GCRoots作为起始节点,顺着引用链遍历,能遍历到的对象就是存活对象,遍历不到的就是垃圾对象。常见的GCRoots:虚拟机栈中局部变量表引用的对象本地方法栈JNI引用的对象方法区中静态变量、常量引用的对象正在运行的线程对象3、简单说下JVM堆内存的分区结构HotSpotJVM堆内存主要分为年轻代和老年代,默认比例1:2,可以通过参数调整:1)年轻代(新生代)存放刚创建的新对象,绝大多数对象都是朝生夕灭的,回收频率高。分为1个Eden区+2个Survivor区(From、To),默认比例8:1:1。Eden区负责主要对象分配,两个Survivor区用来存放每次MinorGC后存活的对象,始终保证一块Survivor区为空,用于复制轮换。2)老年代存放存活时间久、年龄大的对象,比如多次GC后依然存活的对象、大对象。对象存活率高、回收频率低,每次回收耗时更长。补充:JDK8及之后取消了永久代,替换为元空间,元空间属于本地内存,不再占用堆内存,主要存放类元数据、方法信息等,基本不会出现永久代溢出问题。4、MinorGC、MajorGC、FullGC的区别?1)MinorGC(新生代GC)只针对年轻代进行垃圾回收,触发频率高、速度快。大多数新对象创建在Eden区,Eden区满了就会触发MinorGC,清理无效对象,将存活对象转移到Survivor区。过程会有短暂的STW(StopTheWorld),暂停所有用户线程。2)MajorGC(老年代GC)只针对老年代回收,触发次数少、速度慢。通常是老年代空间不足时触发,很多时候会伴随MinorGC,耗时远大于新生代GC。3)FullGC(整堆GC)对整个堆内存(新生代+老年代)甚至元空间统一回收,是代价最高的GC。触发场景包括:手动调用System.gc()、老年代空间严重不足、MinorGC后晋升老年代失败、元空间溢出等。频繁FullGC是线上服务卡顿、吞吐量下降的核心原因。二、GC算法核心类(中级核心)1、常见的GC算法有哪些?各自优缺点?1)标记-清除算法流程:先遍历标记所有存活对象,再统一清除未标记的垃圾对象。优点:逻辑简单,不需要移动对象。缺点:回收后会产生大量内存碎片,后续大对象无法分配连续内存;整体效率偏低。2)复制算法流程:将内存分为两块对等区域,只使用其中一块,GC时把存活对象复制到另一块空闲区域,然后清空当前区域。年轻代就是基于复制算法实现。优点:无内存碎片、内存分配规整、回收速度快。缺点:需要预留一半空闲内存,内存利用率低;对象存活数量多的时候,复制成本极高。3)标记-整理算法流程:先标记存活对象,再将所有存活对象向内存一端移动、紧凑排列,最后清理边界外所有垃圾对象。老年代主要使用该算法。优点:无内存碎片,内存利用率高。缺点:需要移动对象、调整引用地址,耗时比标记清除更长,STW时间更长。2、为什么新生代用复制算法,老年代用标记整理?新生代对象特点是存活率极低、回收频繁,绝大部分对象一次GC就会被回收。使用复制算法,需要复制的存活对象极少,效率极高,且能完美规避内存碎片问题,适配新生代场景。老年代对象特点是存活率高、对象体积大、回收频率低。如果用复制算法,需要复制大量对象,成本极高,且会浪费一半内存空间;而标记整理算法虽然速度慢,但不会产生内存碎片、内存利用率高,更适合老年代的内存特性。3、对象晋升老年代的规则是什么?新生代对象经过一次次MinorGC,存活年龄会递增,满足以下条件就会晋升到老年代:1、年龄阈值达标:默认对象存活15次GC后晋升,可通过-XX:MaxTenuringThreshold调整;2、动态年龄判定:Survivor区中相同年龄对象总和大于Survivor区一半容量时,该年龄及以上对象直接晋升老年代;3、大对象直接晋升:超过Eden区容量的大对象,不会进入新生代,直接分配到老年代,避免新生代复制时的开销;4、MinorGC后存活对象过多,Survivor区放不下,剩余对象直接晋升老年代。三、垃圾收集器类(面试重点)1、讲讲你熟悉的几款垃圾收集器及适用场景主流收集器分为串行、并行、并发三类,不同JDK版本默认收集器不同,生产环境常用组合如下:1)Serial/SerialOld(串行收集器)单线程收集器,GC时暂停所有用户线程,单线程完成回收。简单高效、内存占用小,没有线程切换开销,适合客户端、单机小内存程序、嵌入式设备,服务端基本不用。2)ParallelScavenge/ParallelOld(并行收集器)JDK1.8默认收集器,多线程并行回收,主打高吞吐量,优先最大化利用CPU资源,缩短总GC耗时。GC时依然会STW,暂停用户线程。适合后台任务、批量处理、对延迟不敏感、追求吞吐量的服务。3)CMS(并发标记清除收集器)经典的低延迟收集器,主打低停顿,让GC线程和用户线程尽量并发执行,减少STW时间。适合互联网线上服务、对响应速度要求高的场景。缺点:基于标记清除算法,会产生内存碎片;并发阶段占用CPU,降低吞吐量;存在浮动垃圾,无法处理极速产生的大量对象。JDK9开始废弃,JDK14彻底移除。4)G1(Garbage-First)JDK9默认收集器,兼顾吞吐量和低延迟。核心特点是分区回收,把整个堆内存划分为多个大小相等的Region,不再严格区分新生代老年代,优先回收垃圾最多的分区,收益最高。支持可预测的停顿时间,适合大内存、低延迟、中大型线上服务,是目前生产环境最通用的收集器。5)ZGC/Shenandoah(新一代低延迟收集器)JDK11推出ZGC,JDK12推出Shenandoah,主打超低停顿,STW时间控制在十毫秒甚至毫秒级,几乎不影响业务响应。适合超高并发、极致低延迟、大堆内存的核心业务,目前逐步普及。2、CMS的GC流程是什么?CMS整个过程分为4个阶段,只有两个阶段会停顿用户线程:1、初始标记(STW):短暂暂停,只标记GCRoots直接关联的对象,速度极快;2、并发标记:GC线程和用户线程同时运行,顺着引用链遍历标记所有存活对象,耗时最长但不暂停业务;3、重新标记(STW):暂停用户线程,修正并发标记期间,因用户线程运行产生的新垃圾、引用变动的对象;4、并发清除:并发清理所有垃圾对象,不暂停业务。核心优势:大部分阶段并发执行,大幅减少停顿时间;核心短板:产生内存碎片、存在浮动垃圾。3、G1和CMS的核心区别?生产如何选择?核心区别:1、内存结构:CMS是传统分代模型,严格区分新生代老年代;G1采用分区模型,弱化分代,动态划分新生代和老年代分区;2、回收策略:CMS全量回收老年代;G1按需回收,优先回收垃圾最多的分区,效率更高;3、停顿控制:CMS无法精准控制停顿时间;G1支持设置预期停顿时间,自适应调节回收策略;4、内存碎片:CMS标记清除产生大量碎片;G1回收后会做内存整理,碎片极少。生产选择原则:1、小堆、追求极致吞吐量、业务对延迟不敏感:用Parallel;2、中小堆、追求低延迟、老业务稳定运行:可沿用CMS;3、大堆内存、需要兼顾吞吐量和延迟、线上核心服务:优先G1;4、极致低延迟、高并发核心服务:升级JDK11+使用ZGC。四、调优与线上问题(高阶面试)1、什么是STW?为什么GC必须有STW?STW就是StopTheWorld,GC执行期间暂停所有Java用户线程,只保留GC线程运行。必须STW的核心原因:如果GC标记、移动对象的同时,业务线程还在修改引用、创建对象、销毁对象,会导致标记结果错乱、漏标对象、误删存活对象,GC结果完全不可信。所有收集器都有STW,只是停顿时长不同,低延迟收集器的核心优化目标就是最大限度缩短STW时间。2、频繁FullGC的常见原因及排查思路?常见原因:内存泄漏:长生命周期集合、静态变量、线程池、缓存未清理对象,导致老年代持续膨胀;大对象过多:大量大对象直接进入老年代,快速占满老年代空间;堆内存分配过小,新生代、老年代比例不合理;代码手动调用System.gc(),触发主动FullGC;元空间不足、类加载过多,触发GC。线上排查流程:1、查看GC日志,确认GC类型、停顿时间、堆内存各区域占用变化;2、导出堆dump文件,通过MAT、JProfiler分析大对象、泄漏对象;3、排查代码集合使用、缓存策略、线程池对象持有情况;4、检查JVM参数,调整堆大小、分代比例、大对象阈值、晋升年龄;5、排查是否存在手动GC、定时任务频繁创建销毁大对象的场景。3、内存泄漏和内存溢出的区别?内存泄漏:程序中无用对象持续被引用,GC无法回收,长期占用内存,内存只增不减。属于代码bug,是缓慢的内存堆积过程,不会立刻报错。内存溢出(OOM):堆内存已经被占满,无法分配新的对象内存,程序直接抛出OOM异常、服务崩溃。核心关系:长期内存泄漏,最终一定会导致内存溢出。4、简单说说JVMGC调优的核心思路GC调优的核心目标只有两个:降低GC频率、缩短GC停顿时间,整体遵循以下思路:1、合理设置堆内存大小:避免堆过小导致频繁GC,也避免堆过大导致单次GC耗时过长;2、优化分代比例:根据业务对象生命周期调整新生代、老年代比例,减少对象过早晋升老年代;3、适配收集器:根据业务需求选择收集器,吞吐选Parallel,低延迟选G1/ZGC;4、规避内存泄漏:优先修复代码层面的泄漏问题,这是最根本的优化;5、限制大对象、优化对象创建逻辑,减少短期大量对象爆发;6、开启GC日志,线上持续监控GC指标,针对性优化。五、高频刁钻简答题1、对象一定在堆上分配吗?不一定。JVM会通过逃逸分析优化,未发生逃逸的局部对象,会直接分配在栈上,方法执行结束后随栈帧销毁,无需GC回收,效率更高。只有发生对象逃逸、被外部引用的对象,才会分配到堆内存。2、Survivor区为什么要设置两个,一个不行吗?只用一个Survivor区会出现
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- GB/T 34630.2-2026搅拌摩擦焊铝及铝合金第2部分:焊接接头设计
- 7 接触网新技术应用
- 卷烟卷接设备操作工基础模拟能力考核试卷含答案
- 乙丙橡胶装置操作工岗位体系运行考核试卷含答案
- 碳排放核算员岗中知识掌握考核试卷含答案
- 2025年职校老师考试题库及答案
- 2025年中级会计师经济法试题及答案
- 2025年中级注册安全工程师《安全生产管理》默写本(答案版)
- 2025年中职(康复技术)物理因子治疗试题及答案
- 2025年装配式设计(装配设)试卷及答案
- 苏州小学天文知识竞赛题库及答案
- 2025年华为光芯片笔试题及答案
- 避孕药具发放培训
- 高级波段技术分析价格行为交易系统之区间分析
- 破伤风病例汇报课件
- 《网约车运营管理》教学课件1-2 网约车租赁还车业务
- 2026届浙江温州高三一模高考英语模拟试卷试题(含答案详解)
- 2025年北京市怀柔区六年级语文上册期中考试试卷及答案
- 2025年工会社会工作者招聘笔试题目及解析答案
- 内保单位安全管理条例
- (正式版)DB61∕T 1511-2021 《托幼机构消毒卫生规范》
评论
0/150
提交评论