JVM_GC 面试专题手册
💡 本章节共收录 1844 道面试真题,建议每天复习 10-20 题。
Q1: 请解释Java内存模型(JMM)及其核心概念。
【核心解析】 JMM定义了线程与主内存之间的抽象关系;核心概念包括主内存、工作内存、内存可见性;通过volatile、synchronized等关键字保证可见性和有序性;happens-before原则用于判断数据竞争;JMM是Java并发编程的基础。
Q2: 栈溢出(StackOverflowError)在什么情况下发生?如何避免?
【核心解析】 栈溢出通常由递归调用过深或线程栈帧过多导致;每个线程有固定栈大小,可通过-Xss参数调整;避免方法包括减少递归深度、改用迭代、增大栈空间;注意无限递归或大量局部变量也会导致溢出。
Q3: Stop-The-World(STW)在垃圾回收中是否必须?为什么?
【核心解析】 STW是垃圾回收中暂停所有应用线程的阶段;必须性取决于GC算法:CMS、G1等并发收集器试图减少STW时间,但某些阶段仍需要;STW保证GC过程中对象引用关系的一致性;完全无STW的GC目前难以实现,但ZGC等已大幅缩短STW时间。
Q4: JVM 调优常用参数有哪些?请列举并说明各自作用。
【核心解析】 -Xms 和 -Xmx:设置堆初始大小和最大大小,建议相等避免扩容;-Xmn:设置年轻代大小;-XX:NewRatio:设置老年代与年轻代比例;-XX:SurvivorRatio:设置 Eden 与 Survivor 比例;-XX:MaxTenuringThreshold:设置对象晋升老年代年龄阈值;-XX:+UseG1GC:使用 G1 垃圾收集器;-XX:MaxGCPauseMillis:设置 G1 目标停顿时间;-XX:ParallelGCThreads:设置并行 GC 线程数;-XX:+PrintGCDetails:打印 GC 日志;-XX:MetaspaceSize 和 -XX:MaxMetaspaceSize:设置元空间大小。
Q5: Java程序运行时,JVM内存分为哪几块
【核心解析】 堆(Heap):存放对象实例,是GC主要区域;方法区(Metaspace):存储类信息、常量、静态变量;虚拟机栈:存储局部变量表、操作数栈等;本地方法栈:为Native方法服务;程序计数器:记录当前线程执行的字节码行号。
Q6: 堆里的对象是一定会被回收的吗
【核心解析】 不一定;可达性分析算法中,从GC Roots不可达的对象会被标记为可回收;但对象可能通过finalize()自救;不同GC策略(如CMS、G1)对对象回收时机不同;软引用、弱引用、虚引用对象回收条件不同。
Q7: 引用类型会被回收吗
【核心解析】 强引用:不会被回收,除非不可达;软引用:内存不足时回收;弱引用:下一次GC时回收;虚引用:随时可能回收,主要用于跟踪对象回收;引用队列用于通知引用被回收。
Q8: 常用的垃圾回收器有哪些?
【核心解析】 Serial(串行)、ParNew(并行新生代)、Parallel Scavenge(吞吐量优先)、CMS(并发标记清除)、G1(区域化分代);CMS和G1是常见选择;CMS关注低延迟,G1兼顾吞吐量和延迟。
Q9: JVM调优参数
【核心解析】 堆内存:-Xms、-Xmx;新生代:-Xmn、-XX:SurvivorRatio;元空间:-XX:MetaspaceSize;GC选择:-XX:+UseG1GC、-XX:+UseParallelGC;GC日志:-Xloggc、-XX:+PrintGCDetails;OOM处理:-XX:+HeapDumpOnOutOfMemoryError。
Q10: 内存泄漏排查
【核心解析】 使用jmap生成堆dump;jhat或MAT分析dump,查看大对象和GC roots;jstat监控GC情况;jstack查看线程栈;代码层面注意:静态集合类、未关闭资源、内部类持有外部引用、ThreadLocal未remove。
Q11: 线上遇到过OOM吗?如何排查和解决OOM问题?
【核心解析】 OOM类型:堆溢出、栈溢出、元空间溢出、直接内存溢出;排查命令:jps查看进程、jstat监控GC、jmap生成堆dump、jstack查看线程;分析工具:MAT、VisualVM、JProfiler;常见原因:内存泄漏(如未关闭资源)、大对象分配、GC效率低;解决方案:调整堆大小、优化代码、使用内存池、升级硬件。
Q12: G1和ZGC垃圾回收器有什么区别?
【核心解析】 G1:分代收集,区域化堆,停顿时间可预测;ZGC:不分代,染色指针,并发标记-整理,停顿时间极短(<10ms);ZGC支持大堆(TB级),G1适合中小堆;ZGC内存占用更高。
Q13: JVM内存结构是怎样的?
【核心解析】 堆(年轻代、老年代)、方法区(元空间)、虚拟机栈、本地方法栈、程序计数器;堆是GC主要区域;栈存储局部变量、操作数栈等。
Q14: JVM常见问题排查常用命令有哪些?
【核心解析】 jps:查看Java进程;jstack:查看线程堆栈;jmap:堆转储;jstat:GC统计;jinfo:查看JVM参数;VisualVM、Arthas等工具。
Q15: JVM垃圾回收器有哪些?如何选择CMS和G1?
【核心解析】 常见垃圾回收器:Serial、ParNew、Parallel Scavenge、CMS、G1、ZGC;CMS注重低延迟,适合响应时间敏感的应用;G1兼顾吞吐量和延迟,适合大堆内存(>4GB);CMS使用标记-清除,产生碎片;G1使用标记-整理,可预测停顿;选择依据:堆大小、延迟要求、CPU资源。
Q16: 有哪些JVM垃圾回收器参数?
【核心解析】 -XX:+UseSerialGC、-XX:+UseParNewGC、-XX:+UseConcMarkSweepGC、-XX:+UseG1GC;-XX:ParallelGCThreads、-XX:ConcGCThreads;-XX:MaxGCPauseMillis、-XX:G1HeapRegionSize;-XX:+PrintGCDetails、-XX:+PrintGCDateStamps;-Xms、-Xmx、-Xmn等堆内存参数。
Q17: JVM 的内存模型是怎样的?哪些区域是线程私有的?
【核心解析】 JVM 内存分为堆、方法区、程序计数器、虚拟机栈、本地方法栈;线程私有区域:程序计数器、虚拟机栈、本地方法栈;线程共享区域:堆、方法区。
Q18: JVM 常用的垃圾回收算法有哪些?
【核心解析】 标记-清除算法、标记-复制算法、标记-整理算法、分代收集算法;新生代常用复制算法;老年代常用标记-整理或标记-清除;CMS 和 G1 是具体实现。
Q19: 线上环境新生代回收日志非常频繁,一般是什么情况导致?如何排查和优化?
【核心解析】 对象分配速率过高;新生代空间过小;大对象直接进入老年代;GC线程竞争;排查:使用jstat、GC日志分析工具;优化:调整新生代大小、晋升阈值、对象分配策略
Q20: Java垃圾回收机制:如何判断对象是否存活?常见垃圾回收算法及CMS、G1回收器的工作流程和特点。
【核心解析】 引用计数法(无法解决循环引用);可达性分析(GC Roots);标记-清除(产生碎片);标记-复制(无碎片,浪费空间);标记-整理(无碎片,效率低);CMS:初始标记、并发标记、重新标记、并发清除,低延迟但产生碎片;G1:分区、停顿可预测,避免Full GC
Q21: 谈谈你对多态的理解,以及在JVM中多态是如何实现的?
【核心解析】 多态是同一行为具有不同表现形式;JVM通过虚方法表实现动态分派;方法调用时查找实际类型对应的方法;涉及invokevirtual指令和常量池解析
Q22: V8 引擎的垃圾回收机制是什么?
【核心解析】 V8 采用分代回收,新生代用 Scavenge 算法(Cheney 算法);老生代用标记-清除和标记-整理;增量标记和惰性清理减少停顿;并行和并发回收;对象晋升条件;内存限制和优化。
Q23: GC垃圾回收原理是什么?
【核心解析】 JVM垃圾回收主要针对堆内存;可达性分析算法(GC Roots)标记存活对象;回收算法:标记-清除、标记-复制、标记-整理;分代收集:新生代(复制算法)、老年代(标记-清除/整理);常见GC:Serial、Parallel、CMS、G1、ZGC;触发条件:内存不足、System.gc()等。
Q24: 请解释分代垃圾回收器的工作原理,以及如何判断对象是否可以被回收?哪些对象可以作为GC Roots?
【核心解析】 分代回收基于对象存活周期分为年轻代和老年代,不同代采用不同回收算法;判断对象可回收主要使用可达性分析,从GC Roots出发不可达的对象可回收;GC Roots包括栈帧中的局部变量、静态变量、JNI引用、活跃线程等。
Q25: JVM内存模型分哪些区域?
【核心解析】 程序计数器;Java虚拟机栈;本地方法栈;Java堆;方法区(含运行时常量池);直接内存(非JVM规范但常用)
Q26: Native方法(如C++代码)是如何在JVM中运行的?
【核心解析】 通过JNI(Java Native Interface)调用;本地方法栈存储native方法信息;JVM加载动态链接库(.dll/.so);执行时切换到本地方法栈;返回结果到Java栈
Q27: 内存溢出和内存泄漏的区别及原因?
【核心解析】 内存泄漏:对象无法被GC回收,导致堆内存持续占用;内存溢出:堆内存不足,无法分配新对象;泄漏是溢出的常见原因之一;其他溢出原因:大对象、死循环、内存泄漏积累
Q28: Python的内存管理和垃圾回收与JVM有何不同?
【核心解析】 Python:引用计数为主,标记清除和分代回收为辅;JVM:可达性分析,分代收集;Python没有JVM的堆栈模型;Python的GIL影响并发;JVM有更丰富的GC算法
Q29: 请解释Go语言的垃圾回收机制,以及常见的垃圾回收算法。
【核心解析】 Go使用并发标记-清除(CMS)和三色标记法;GC过程包括标记准备、并发标记、标记终止和清除;三色标记:白色(未访问)、灰色(已访问但未扫描子对象)、黑色(已扫描);写屏障用于保证并发安全;常见算法:标记-清除、标记-复制、标记-整理;Go的GC目标是低延迟。
Q30: 请讲一下JVM的内存区域划分,以及各个JDK版本之间的差异。
【核心解析】 JDK 8之前有永久代,之后被元空间取代;JDK 8及以后字符串常量池从永久代移到堆中;JDK 11引入ZGC等新GC;JDK 17统一了G1作为默认GC;不同版本对堆、栈、方法区等区域的实现细节有调整。
Q31: 请解释年轻代和老年代的垃圾回收算法和策略。
【核心解析】 年轻代使用复制算法(如Minor GC);老年代使用标记-清除或标记-整理算法(如Major GC);分代收集策略:对象优先分配在Eden区,大对象直接进入老年代,长期存活对象晋升老年代;GC调优参数如-Xmn、-XX:SurvivorRatio等。
Q32: 简单说一下Java中的垃圾回收机制。
【核心解析】 GC主要针对堆内存;分代收集:新生代(Minor GC)、老年代(Major GC/Full GC);常见算法:标记-清除、标记-复制、标记-整理;GC Roots可达性分析;常用收集器:CMS、G1、ZGC。
Q33: Java垃圾回收机制是什么?请追问G1垃圾收集器在设计上是如何优化内存分配和回收效率的。
【核心解析】 GC自动管理内存;G1将堆划分为Region;优先回收垃圾最多的Region(Garbage First);使用SATB保证并发标记正确性;通过停顿预测模型控制GC时间;支持大对象直接分配Humongous Region。
Q34: G1的分区机制中,每个分区(Region)的大小是固定的吗?
【核心解析】 G1的Region大小默认根据堆大小自动计算,范围为1MB~32MB,且必须是2的幂;可通过-XX:G1HeapRegionSize参数手动设置;Region大小固定,但数量随堆大小变化。
Q35: Java垃圾回收机制中,如何判断对象已死?常见的垃圾回收算法有哪些?
【核心解析】 引用计数法(无法解决循环引用);可达性分析(GC Roots);标记-清除、标记-复制、标记-整理;分代收集(新生代复制,老年代标记整理或标记清除)。
Q36: 频繁发生Full GC如何解决?
【核心解析】 分析GC日志;调整堆大小;优化代码减少对象创建;检查内存泄漏;调整GC策略;使用G1或ZGC;减少System.gc调用
Q37: Go 的垃圾回收机制是怎样的?
【核心解析】 Go 使用并发标记清除算法;三色标记法(白、灰、黑);写屏障技术保证并发安全;GC 触发条件包括内存分配量和定时;STW 时间较短,通常低于毫秒级;可通过 GOGC 环境变量调整 GC 频率。
Q38: JAVA语言的垃圾回收机制是怎样的?
【核心解析】 JVM通过可达性分析判断对象是否存活;垃圾回收算法包括标记-清除、标记-复制、标记-整理;分代收集:新生代使用复制算法(如ParNew),老年代使用标记-整理(如CMS、G1);GC类型:Minor GC、Major GC、Full GC;调优参数如-Xms、-Xmx、-XX:NewRatio等
Q39: 垃圾回收了解吗?OOM如何排查优化?实际用过MAT吗?
【核心解析】 垃圾回收算法:标记-清除、复制、标记-整理;OOM排查:分析堆转储、使用MAT查看大对象、泄漏链;MAT可分析内存泄漏。
Q40: 请详细描述JVM的内存结构(包括元空间、栈空间、堆内存),并比较CMS和G1垃圾收集器的区别,以及它们是否是并发安全的。
【核心解析】 JVM内存结构包括堆、栈、方法区(元空间)、程序计数器等;CMS和G1都是并发收集器,但CMS注重低停顿,G1注重可预测停顿;CMS使用标记-清除,G1使用区域化分代收集;两者都不是完全并发安全,需要配合其他机制如ConcurrentHashMap的分段锁来保证线程安全。
Q41: JVM的内存区域是怎么划分的?
【核心解析】 堆(Heap):存储对象实例,分新生代(Eden、Survivor)和老年代;方法区(Metaspace):存储类信息、常量、静态变量;虚拟机栈:存储局部变量表、操作数栈、方法出口;本地方法栈:为Native方法服务;程序计数器:记录当前线程执行的字节码行号。
Q42: JVM内存结构是怎样的?
【核心解析】 堆、方法区、虚拟机栈、本地方法栈、程序计数器;堆分为新生代和老年代,方法区存储类信息、常量等
Q43: 类加载过程包括哪些步骤?
【核心解析】 加载、验证、准备、解析、初始化;加载:通过全限定名获取二进制字节流;验证:确保字节流符合规范;准备:为静态变量分配内存并赋默认值;解析:将符号引用转为直接引用;初始化:执行类构造器 <clinit> 方法
Q44: 说一说JVM内存模型,如何结合线上问题讲解?
【核心解析】 JMM(Java内存模型)约束线程间共享变量的可见性,涉及主内存、工作内存、可见性、原子性和有序性;很多并发bug源于线程更新值对其他线程不可见或指令重排导致状态异常;讲解时应将JMM与volatile、锁、CAS等机制关联;结合线上问题:如缓存失效、死循环、内存泄漏等场景分析。
Q45: 比如接口无响应,出现问题,项目的排查思路,如何查看 Full GC 的情况?
【核心解析】 检查 CPU、内存、磁盘 IO;使用 jstat 查看 GC 统计;jmap 堆转储分析;jstack 查看线程堆栈;GC 日志分析;检查 JVM 参数;定位慢 SQL 或死锁;Full GC 频繁原因:大对象、内存泄漏、元空间不足。
Q46: JVM 内存模型是怎样的?垃圾回收机制和常见的垃圾回收器有哪些?
【核心解析】 内存模型包括堆(新生代、老年代)、方法区、虚拟机栈、本地方法栈、程序计数器;垃圾回收算法有标记-清除、标记-复制、标记-整理;常见回收器:Serial、ParNew、CMS、G1、ZGC等。
Q47: 什么是双亲委派模型?它的设计目的是什么?请举例说明如何打破双亲委派模型。
【核心解析】 双亲委派模型:类加载器在加载类时先委托父加载器加载,父加载器无法加载时才自己加载;目的是保证核心类库的安全性和一致性;打破双亲委派的例子:自定义类加载器重写loadClass方法,如Tomcat的WebAppClassLoader。
Q48: 如何观察项目中的Full GC情况?如何解决Full GC问题?jmap可以用来做什么?
【核心解析】 通过JVM监控工具(如jstat、VisualVM、GC日志)查看Full GC频率和耗时;Full GC原因包括老年代空间不足、元空间不足、System.gc()调用、CMS并发模式失败等;解决:调整堆大小、优化对象分配、减少大对象、调整GC策略(如G1);jmap用于生成堆转储快照(heap dump)、查看堆内存统计、打印类加载器信息等。
Q49: 请详细描述JVM的内存模型,包括堆内存的分代结构、各区域的作用,以及为什么采用分代分区设计。
【核心解析】 堆内存分为新生代(Eden、Survivor From/To)和老年代;方法区(元空间)存储类信息、常量等;分代设计基于对象生命周期差异,新生代存放短命对象,老年代存放长命对象,便于采用不同GC算法提高效率。
Q50: 请介绍常见的垃圾回收算法及其优缺点。
【核心解析】 标记-清除:效率低、产生碎片;标记-复制:无碎片但浪费空间;标记-整理:无碎片但效率略低;分代收集:结合多种算法。
Q51: JVM 调优常用参数有哪些?请举例说明。
【核心解析】 堆内存设置:-Xms、-Xmx;新生代大小:-Xmn;元空间:-XX:MetaspaceSize;GC选择:-XX:+UseG1GC、-XX:+UseParallelGC;GC日志:-Xloggc:gc.log;OOM时自动dump:-XX:+HeapDumpOnOutOfMemoryError;调整线程栈:-Xss。
Q52: 请描述Java运行时内存区域划分,以及对象垃圾回收的分代区域。
【核心解析】 运行时内存区域:程序计数器、虚拟机栈、本地方法栈、堆、方法区(元空间/永久代);堆分代:新生代(Eden、Survivor From/To)、老年代;方法区:存储类信息、常量、静态变量等;垃圾回收主要针对堆和方法区。
Q53: 请说明CMS垃圾回收器的步骤,以及为什么需要STW(Stop-The-World)。
【核心解析】 CMS步骤:初始标记(STW)、并发标记、重新标记(STW)、并发清除;STW原因:防止在标记或清理过程中对象引用发生变化导致错误;不暂停的影响:并发标记时对象引用变化可能导致漏标或错标,影响垃圾回收准确性。
Q54: 线上Full GC怎么去排查?
【核心解析】 查看GC日志(-XX:+PrintGCDetails);使用jstat、jmap、jstack等工具;分析堆转储文件(MAT、JProfiler);检查内存泄漏、大对象、元空间不足、GC参数不合理。
Q55: 对象分配一定在堆上吗?请解释逃逸分析和栈上分配。
【核心解析】 对象不一定在堆上分配;通过逃逸分析,如果对象不逃逸出方法或线程,可以在栈上分配;栈上分配减少GC压力;JVM参数-XX:+DoEscapeAnalysis启用逃逸分析;标量替换进一步优化。
Q56: 请介绍各种垃圾回收器的使用场景和特点。
【核心解析】 Serial:单线程,适合单核或小内存;ParNew:多线程,配合CMS;Parallel Scavenge:吞吐量优先,适合后台计算;CMS:低延迟,但可能产生碎片;G1:大堆,可预测停顿;ZGC:超低延迟,大堆;Shenandoah:低延迟,并发。
Q57: 分代垃圾回收器的工作原理是什么?
【核心解析】 堆内存分为新生代和老年代;新生代使用复制算法,分为Eden和两个Survivor区;对象优先在Eden分配,Minor GC后存活对象移至Survivor;老年代使用标记-清除或标记-整理算法;Major GC触发条件包括老年代空间不足等
Q58: 垃圾回收如何判断对象是否可以被回收?
【核心解析】 引用计数法(难以解决循环引用);可达性分析算法;从GC Roots对象出发,不可达的对象判定为可回收;GC Roots包括栈帧中引用、静态引用、JNI引用等;对象可经历两次标记才被回收
Q59: 哪些对象可以作为GC Roots?
【核心解析】 虚拟机栈中引用的对象;方法区中静态属性引用的对象;方法区中常量引用的对象;本地方法栈中JNI引用的对象;活跃线程的Thread对象;Java虚拟机内部的引用(如系统类加载器)
Q60: JVM 中双亲委派机制是什么?如何打破?
【核心解析】 类加载器先委托父加载器加载;打破:自定义类加载器重写loadClass方法;如Tomcat、SPI
Q61: JVM内存区域中,新生代和老年代分别有什么特点?对象如何晋升到老年代?
【核心解析】 新生代:Eden、Survivor(From/To),Minor GC频繁;老年代:存放长期存活对象,Major GC频率低;晋升条件:年龄阈值(默认15)、大对象直接进入老年代、动态年龄判定;空间分配担保机制
Q62: 最新的垃圾回收器是什么?请详细说明G1垃圾回收器的工作流程。
【核心解析】 最新垃圾回收器包括ZGC和Shenandoah;G1将堆划分为多个Region;工作流程:初始标记、并发标记、最终标记、筛选回收;G1通过维护Remembered Set和Card Table实现跨Region引用;目标是在低延迟下控制停顿时间。
Q63: 你了解G1垃圾回收器的底层原理吗?G1标记完需要回收的region后,具体如何判断是否该对一个region进行清理?
【核心解析】 G1将堆划分为多个Region,通过Remembered Set维护跨Region引用;标记阶段使用SATB(Snapshot-At-The-Beginning)算法;回收时根据Region的垃圾比例和回收收益(停顿时间预测)决定是否清理;优先回收垃圾最多的Region(Garbage First);通过Mixed GC回收部分年轻代和老年代Region。
Q64: 如何排查GC问题?
【核心解析】 使用jstat、jmap、jstack等工具监控GC日志;分析GC频率、停顿时间、内存占用;检查堆内存配置是否合理;排查是否存在内存泄漏;调整GC算法和参数(如-XX:+UseG1GC);结合业务场景优化对象生命周期。
Q65: JVM垃圾回收策略有哪些?为什么分新生代和老年代?
【核心解析】 垃圾回收策略包括标记-清除、标记-复制、标记-整理;分代收集基于对象存活周期不同,新生代对象存活率低,适合复制算法;老年代对象存活率高,适合标记-清除或标记-整理;分代可以提高回收效率。
Q66: 你所用的Java版本中,垃圾回收算法是什么?请说明其原理。
【核心解析】 以JDK 8为例,默认使用Parallel Scavenge(新生代)和Parallel Old(老年代);新生代采用复制算法,老年代采用标记-整理算法;JDK 11+默认使用G1,基于Region分代,采用复制和标记-整理混合。
Q67: JVM调优中,出现OOM如何排查?
【核心解析】 使用jmap生成堆转储文件;通过MAT或VisualVM分析大对象和内存泄漏;检查GC日志,调整堆大小和垃圾回收器;排查代码中未释放的资源(如ThreadLocal、连接池)。
Q68: JVM内存区域有哪些?垃圾回收策略有哪些?
【核心解析】 内存区域:堆、方法区、虚拟机栈、本地方法栈、程序计数器;堆分新生代和老年代;垃圾回收策略:标记-清除、标记-复制、标记-整理;分代收集:新生代用复制算法,老年代用标记-整理或标记-清除。
Q69: 了解哪些垃圾回收器?
【核心解析】 Serial、ParNew、Parallel Scavenge、CMS、G1、ZGC、Shenandoah;Serial单线程,适合单核;CMS并发低停顿;G1分区,可预测停顿;ZGC低延迟,支持大堆。
Q70: G1为什么要分多Region,这么做的好处是什么?
【核心解析】 将堆划分为多个大小相等的Region,便于并行回收;避免全堆扫描,提高效率;可预测停顿时间,通过设置目标停顿时间;支持混合收集,同时处理新生代和老年代。
Q71: 请解释Java的GC机制和内存管理。
【核心解析】 Java堆分为新生代(Eden、Survivor)和老年代;GC算法包括标记-清除、标记-复制、标记-整理;常见GC:Serial、Parallel、CMS、G1;内存管理包括堆、栈、方法区等。
Q72: JVM内存回收中,标记清除和标记整理算法分别适用于什么场景?如何定义对象存活时间?
【核心解析】 标记清除适用于老年代,存活对象少、碎片化不严重时;标记整理适用于老年代,存活对象多、需要减少碎片时;存活时间通过分代收集、年龄计数器定义,对象在年轻代经历多次Minor GC后晋升到老年代;标记清除会产生内存碎片,标记整理会移动对象;实际中CMS使用标记清除,G1使用标记整理;存活时间阈值可通过-XX:MaxTenuringThreshold调整。
Q73: JVM内存结构以及是否调优过?
【核心解析】 堆、栈、方法区、程序计数器;调优参数:-Xms、-Xmx、-XX:NewRatio、-XX:SurvivorRatio、-XX:+UseG1GC等
Q74: G1的region设置的是数量还是大小?设置的数量大了或小了有什么影响?
【核心解析】 G1的region大小由-XX:G1HeapRegionSize指定,数量由堆大小除以region大小自动计算;region数量多:分配更灵活,但GC扫描更多region;region数量少:分配粒度大,可能导致大对象直接进入Humongous区域;region大小建议1-32MB,通常2048个左右
Q75: JVM 的内存区域划分是怎样的?栈的作用是什么?
【核心解析】 JVM 内存分为堆、方法区、虚拟机栈、本地方法栈、程序计数器;栈(虚拟机栈)用于存储局部变量表、操作数栈、动态链接、方法出口等;每个方法调用对应一个栈帧,栈帧入栈出栈;栈是线程私有的,生命周期与线程相同;栈大小影响递归深度,可能抛出 StackOverflowError。
Q76: 方法中new一个对象并赋值给局部变量,涉及到哪些JVM结构?
【核心解析】 栈帧中的局部变量表;堆中对象分配;TLAB;GC根(栈引用);方法区(类信息);执行引擎;内存屏障
Q77: new一个对象的完整过程是什么?
【核心解析】 类加载检查(检查常量池中是否有类的符号引用);分配内存(指针碰撞或空闲列表,CAS+失败重试保证线程安全);初始化零值(所有实例字段设为默认值);设置对象头(Mark Word、类型指针、数组长度等);执行 <init> 方法(按顺序执行实例变量初始化和构造代码块)。
Q78: 双亲委派模型了解吗?
【核心解析】 类加载器层次:启动类加载器、扩展类加载器、应用程序类加载器;工作流程:先委托父加载器加载,父加载器无法加载才由子加载器加载;优点:避免重复加载、保证核心类库安全(防止自定义java.lang.Object);打破双亲委派:自定义类加载器重写loadClass方法,如Tomcat的WebAppClassLoader。
Q79: 请解释JVM内存模型和垃圾回收机制。
【核心解析】 内存模型:堆(新生代、老年代)、方法区、虚拟机栈、本地方法栈、程序计数器;垃圾回收:标记-清除、标记-复制、标记-整理;分代回收;GC Roots可达性分析。
Q80: JMM如何实现可见性、原子性和有序性?
【核心解析】 可见性:volatile关键字、synchronized、final;原子性:synchronized、Lock、CAS;有序性:happens-before规则、volatile禁止指令重排;内存屏障实现
Q81: JVM调优常用参数有哪些?请举例说明。
【核心解析】 -Xms/-Xmx设置堆大小;-Xmn设置新生代大小;-XX:MetaspaceSize设置元空间;-XX:+UseG1GC选择GC;-XX:MaxGCPauseMillis目标停顿时间;-XX:ParallelGCThreads并行线程数;-XX:+PrintGCDetails打印GC日志
Q82: Java的垃圾回收机制?
【核心解析】 Java垃圾回收(GC)自动管理堆内存,回收不再使用的对象;主要算法:标记-清除、标记-复制、标记-整理;分代收集:新生代(Minor GC,复制算法)、老年代(Major GC/Full GC,标记-整理或标记-清除);常用GC:Serial、Parallel、CMS、G1、ZGC;GC调优参数:-Xms、-Xmx、-XX:NewRatio、-XX:SurvivorRatio等。
Q83: 线上Full GC如何排查?
【核心解析】 查看GC日志(-XX:+PrintGCDetails);使用jstat、jmap、jstack;分析堆转储(MAT、JProfiler);定位大对象、内存泄漏、GC参数不合理
Q84: 说说G1垃圾回收器和ZGC垃圾回收器。
【核心解析】 G1:面向服务端,低停顿,分代收集,Region划分,可预测停顿时间,通过混合GC回收;ZGC:低延迟(<10ms),不分代,基于染色指针和读屏障,支持TB级堆,并发标记-整理;区别:G1分代,ZGC不分代;G1停顿略高,ZGC更低;G1适合大堆,ZGC适合超大堆;ZGC实现更复杂
Q85: 请描述JVM运行时数据区。
【核心解析】 包括:程序计数器、虚拟机栈、本地方法栈、堆(新生代、老年代)、方法区(元空间/永久代);线程私有:程序计数器、栈;线程共享:堆、方法区。
Q86: 请解释JVM类加载机制。
【核心解析】 加载、验证、准备、解析、初始化;双亲委派模型:Bootstrap ClassLoader、Extension ClassLoader、Application ClassLoader;打破双亲委派:自定义ClassLoader、SPI等。
Q87: JVM 调优参数有哪些,如何根据应用场景调整堆内存、GC 策略等。
【核心解析】 常见参数:-Xms/-Xmx 设置堆大小、-XX:NewRatio 新生代比例、-XX:SurvivorRatio Eden 与 Survivor 比例、-XX:+UseG1GC 选择 GC 收集器、-XX:MaxGCPauseMillis 目标停顿时间、-XX:MetaspaceSize 元空间大小;调优需监控 GC 日志,调整堆大小和收集器以降低停顿和吞吐量。
Q88: Java中强引用、软引用、弱引用、虚引用在GC时有什么区别?
【核心解析】 强引用:只要可达就不回收;软引用:内存不足时回收;弱引用:下次GC即回收;虚引用:无法通过get获取对象,用于对象回收跟踪。
Q89: 请介绍常见的垃圾回收算法和垃圾回收器。
【核心解析】 垃圾回收算法:标记-清除、标记-复制、标记-整理、分代收集;垃圾回收器:Serial、ParNew、Parallel Scavenge、CMS、G1、ZGC;CMS注重低停顿,G1兼顾吞吐量和停顿时间,ZGC低延迟。
Q90: G1垃圾回收器的实现原理是什么?
【核心解析】 基于Region的内存布局;优先回收价值最大的Region;使用SATB(Snapshot-At-The-Beginning)算法处理并发标记;通过Remembered Set避免全堆扫描;可预测停顿时间模型
Q91: JVM频繁Full GC如何排查?
【核心解析】 查看GC日志;使用jstat、jmap等工具;分析堆转储文件;检查内存泄漏;调整堆大小和GC策略;优化代码减少对象创建
Q92: JVM的内存区域有哪些?各自的作用是什么?常见的垃圾回收算法和垃圾回收器有哪些?
【核心解析】 内存区域:堆(对象实例)、栈(局部变量)、方法区(类信息)、程序计数器、本地方法栈;GC算法:标记-清除、标记-复制、标记-整理、分代收集;回收器:Serial、ParNew、Parallel Scavenge、CMS、G1、ZGC。
Q93: 请详细描述JVM运行时数据区(内存空间)的组成,包括各区域的作用、是否线程私有以及可能发生的异常。
【核心解析】 程序计数器(线程私有,无OOM);虚拟机栈(线程私有,StackOverflowError和OOM);本地方法栈(线程私有);堆(线程共享,OOM);方法区(线程共享,OOM,含运行时常量池);直接内存(NIO,OOM)
Q94: 请解释JVM类加载机制,包括类加载的七个阶段、双亲委派模型及其作用。
【核心解析】 加载、验证、准备、解析、初始化、使用、卸载;双亲委派模型:自底向上检查类是否已加载,自顶向下尝试加载;作用:避免重复加载,保证核心类库安全
Q95: 介绍一下JVM的内存模型(结构)。
【核心解析】 程序计数器;Java虚拟机栈;本地方法栈;堆(年轻代、老年代、元空间/永久代);方法区(运行时常量池);直接内存(NIO)。
Q96: 本地方法栈怎么快速造成OOM?
【核心解析】 通过无限递归调用本地方法;大量创建线程并分配本地方法栈空间;设置过小的本地方法栈大小(-Xss);使用JNI调用导致内存泄漏;结合死循环或递归深度过大。
Q97: 堆区有一个for循环,里面new一个对象,这个for循环次数多,会发生OOM吗?
【核心解析】 不一定,取决于对象是否被引用;如果对象在循环内被垃圾回收,则不会OOM;如果对象被外部引用(如加入集合),则可能OOM;可通过调整堆大小(-Xmx)避免;需注意内存泄漏风险。
Q98: G1如何精确控制STW的时间?
【核心解析】 通过设置-XX:MaxGCPauseMillis目标停顿时间;G1会预测每个区域的回收时间,选择回收价值高的区域;使用并发标记和混合收集;动态调整年轻代大小和回收区域数量;通过自适应调整实现。
Q99: Java中new创建的对象是如何回收的?请简述垃圾回收机制。
【核心解析】 对象回收通过垃圾收集器自动进行;主要算法:标记-清除、标记-复制、标记-整理;分代收集:新生代(Minor GC)使用复制算法,老年代(Major GC)使用标记-整理或标记-清除;可达性分析判断对象是否存活;常见收集器:CMS、G1、ZGC等。
Q100: JVM内存结构是怎样的?哪些区域会发生OOM(OutOfMemoryError)?请举例说明。
【核心解析】 堆、方法区、虚拟机栈、本地方法栈、程序计数器;堆OOM(对象过多)、方法区OOM(类加载过多)、虚拟机栈OOM(递归过深)、本地方法栈OOM;直接内存也可能OOM。
Q101: 请详细描述JVM的GC设计,包括内存结构(堆、栈、方法区等)和常见的垃圾回收算法(标记-清除、复制、标记-整理、分代收集),以及各代常用的回收器(如Serial、Parallel、CMS、G1等)。
【核心解析】 内存结构:堆(新生代、老年代)、方法区(元空间/永久代)、虚拟机栈、本地方法栈、程序计数器;回收算法:标记-清除(碎片问题)、复制(新生代)、标记-整理(老年代)、分代收集;新生代回收器:Serial(单线程)、ParNew(多线程)、Parallel Scavenge(吞吐量优先);老年代回收器:Serial Old、Parallel Old、CMS(低延迟)、G1(分区、可预测停顿);GC触发条件:Minor GC、Major GC、Full GC;调优参数:-Xms、-Xmx、-XX:NewRatio、-XX:SurvivorRatio等。
Q102: 说下你对Java内存模型的理解?JDK8的内存模型有哪些改进措施?
【核心解析】 Java内存模型(JMM)规定线程间共享变量可见性、原子性、有序性,通过volatile、synchronized等实现;JDK8改进:永久代改为元空间(Metaspace),使用本地内存,避免OOM;字符串常量池移至堆。
Q103: 说下有哪些垃圾回收器?JDK9的默认垃圾回收器是什么?
【核心解析】 常见GC:Serial、ParNew、Parallel Scavenge、CMS、G1、ZGC(JDK11+);JDK9默认GC是G1(Garbage-First),特点:分区管理、可预测停顿、并行与并发。
Q104: G1垃圾收集器如何精确控制STW的时间?
【核心解析】 通过设置-XX:MaxGCPauseMillis参数指定目标停顿时间;G1将堆划分为多个Region,通过预测模型选择回收收益最大的Region集合;使用并发标记和混合回收阶段,避免全堆扫描;通过调整年轻代大小、并行线程数等参数优化停顿时间。
Q105: 介绍一下JVM的内存模型(结构)。本地方法栈怎么快速造成OOM?
【核心解析】 JVM内存结构:堆、方法区、程序计数器、虚拟机栈、本地方法栈;本地方法栈OOM:通过递归调用本地方法或分配大量本地内存(如JNI)快速耗尽。
Q106: JVM内存结构包括哪些区域?
【核心解析】 包括程序计数器、虚拟机栈、本地方法栈、堆和方法区(元空间);堆分为新生代(Eden、Survivor From/To)和老年代;方法区存储类信息、常量、静态变量等。
Q107: Minor GC、Major GC和Full GC的触发条件是什么?
【核心解析】 Minor GC在Eden区满时触发;Major GC通常指老年代GC,触发条件包括老年代空间不足、CMS并发模式失败等;Full GC触发条件包括老年代空间不足、方法区空间不足、System.gc()调用、Minor GC晋升对象大小超过老年代剩余空间等。