整理秋招遇见的JVM题

那些杀不死我的 反复追着我杀!!

1.jvm包含哪几部分
classloader:将编译(.java->.class)好的java字节码文件(.class文件) 加载到内存中(也就是运行时数据区
Runtime data area 存放运行时数据(线程私有:栈 本地方法栈 pc ,进程级(也就是所有线程共享):堆 本地方法区)
Execution engine 执行引擎,class文件被加载后 将指令和数据放在内存中 执行引擎负责将命令解释给os 也就是将JVM指令翻译为os指令集
Native interface:本地库接口

2.jvm内存结构/运行时数据区
线程私有的:栈(每个方法执行时创建栈帧 存局部变量表等) 本地方法栈(为Native方法提供服务) 程序计数器(存当前线程执行的字节码指令地址)
线程共享:堆(最大的内存区 存对象实例、类对象) 方法区 (存类有关的信息 静态变量等)

3.说一下永久代和元空间
都是对 方法区 的实现
永久代:JDK7 及之前的实现,属于堆内存的一部分,有固定大小限制(通过-XX:PermSize/-XX:MaxPermSize设置),存储类元信息、常量池等,易触发永久代 OOM
元空间:JDK8 及之后的实现,使用本地内存(不在堆中),大小受物理内存限制(默认无上限),仅需通过-XX:MetaspaceSize设置初始触发 GC 的阈值

4.为什么jdk8要将永久代替换为元空间
解决永久代OOM问题 简化类元数据管理 兼容JVM规范

5.类加载过程
加载:通过类全限定名获取字节码流,将字节码转化为方法区的类元数据,同时在堆中生成Class对象
验证:确保字节码符合 JVM 规范(如文件格式验证、语义验证),防止恶意字节码破坏 JVM 安全
准备:为类的静态变量分配内存并赋默认值(如 int 赋 0、对象赋 null),不执行赋值语句(赋值在初始化阶段)
解析:将常量池中的符号引用替换为直接引用(如类、方法的内存地址),该阶段可延迟到初始化后执行。
初始化:执行<clinit>方法(静态变量赋值 + 静态代码块),触发时机是 “主动使用”(new 对象、访问静态成员、反射、初始化子类、主类),且每个类仅初始化一次

6.类加载机制(双亲委派制)
1类加载器收到加载请求  -> 2将请求委托给父加载器,一直向上委托,直到启动类加载器 -> 3启动加载器检查是否能加载这个类,能则使用当前加载器,否则向下传递 ->4重复步骤3 如果找不到 class not found
JVM 默认类加载器层级:启动类加载器(Bootstrap)→扩展类加载器(Ext)→应用程序类加载器(App)→自定义类加载器

7.why双亲委派
保护核心类库(如String由启动类加载器加载,避免自定义类篡改替换)
防止类重复加载

8.自定义类加载器需要注意什么
重写findClass方法(not loadClass,避免破坏双亲委派)

9.双亲委派模型有哪些破坏场景 为什么要破坏
Tomcat的WebAppClassLoader:Tomcat 为每个 Web 应用创建独立类加载器,优先加载应用内的类(而非委托父类),目的是隔离不同 Web 应用的类(防止不同应用的同包同类冲突)
JDBC 的 SPI 加载:JDBC 的核心接口java.sql.Driver由启动类加载器加载,但具体实现(如 MySQL 驱动)在第三方包,启动类加载器无法加载,因此 DriverManager 通过线程上下文类加载器(破坏双亲委派)加载实现类(可能会让详细说一下SPI机制
一些热部署实现:自定义类加载器加载更新后的类

10.类卸载条件
类所有实例被完全回收 类加载器被完全回收 Class对象无任何引用
(FullGC时发生

11.介绍一下gc机制
涉及对象可回收判定、垃圾收集算法、分代收集模型、垃圾收集器、GC 触发时机等维度(问这么大 吟唱启动

12.常见gc算法
标记-清除,标记-复制,标记-整理,分代收集

13.介绍一下CMS和G1
(1)CMS 收集器(老年代专用)
核心流程:初始标记(STW,标记 GC Roots 直接关联对象)→并发标记(无 STW,遍历引用链)→重新标记(STW,修正并发标记的遗漏)→并发清除(无 STW,清理可回收对象)
优点:并发收集,STW 时间短,适合低延迟场景
缺点:产生内存碎片、CPU 消耗高(并发阶段占用 CPU)、依赖老年代空间预留(易触发 Full GC)
(2)G1 收集器(全堆收集)
核心流程:将堆划分为多个大小相等的 Region,包含新生代 Region 和老年代 Region;流程为初始标记→并发标记→最终标记→筛选回收(STW,优先回收垃圾多的 Region)
优点:兼顾吞吐量和延迟、可预测 STW 时间(通过-XX:MaxGCPauseMillis设置)、无内存碎片(回收时整理 Region)
缺点:内存占用高(维护 Remembered Set)、小内存场景下性能不如 CMS

14.jvm如何判断对象是可回收的
早期方案引用计数法(无法解决循环引用问题)
可达性分析算法判定对象是否不可达,结合引用类型细分可回收时机,finalize 机制完成最终判定

15.能否将对象分配在栈上
jvm针对“逃逸”做了优化
分析对象的作用域是否逃出方法 / 线程,若逃逸则可直接分配在栈上 无需gc

16.jvm调优核心思路是什么
监控 分析 参数调整 验证

17.一般会调整哪些jvm参数
堆大小:-Xms2g -Xmx2g(初始堆 = 最大堆,避免堆动态扩展的开销)
新生代大小:-Xmn512m(新生代占堆的 1/4~1/3,过小会导致对象提前进入老年代)
Survivor 比例:-XX:SurvivorRatio=8(Eden:S0:S1=8:1:1,保证新生代对象有足够空间存活)
晋升老年代年龄:-XX:MaxTenuringThreshold -XX:InitialTenuringThreshold
GC 收集器:-XX:+UseG1GC(默认推荐,兼顾吞吐量和延迟)、-XX:+UseZGC(低延迟场景)
GC 日志:-XX:+PrintGCDetails -Xloggc:gc.log(输出 GC 日志用于分析)
元空间:-XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=256m(限制元空间大小,避免元空间 OOM)

18.Jvm调优经验
《没有经验!!》(回去等通知吧

19.内存泄漏和OOM的区别?如何排查
(1)内存泄漏:对象已无业务意义,但仍被引用(如ThreadLocal......),导致无法被 GC 回收,长期积累会引发 OOM
① jmap -dump:format=b,file=heap.hprof导出堆快照;② MAT分析快照,定位 “无法回收的大对象” 和 “持有其引用的 GC Roots ③结合 Arthas 的jvm/heapdump命令定位泄漏代码(如静态 Map 未清理)
(2)OOM:JVM 内存不足(如堆 / 元空间 / 栈超出上限),无法为新对象分配内存,直接抛出 OOM 异常
① 看 OOM 类型(堆 OOM / 元空间 OOM / 栈 OOM)② 堆 OOM 分析对象分布(是否大对象过多) 元空间 OOM 检查类加载数量(是否频繁动态生成类) 栈 OOM 检查递归深度或线程数

20.线上OOM问题如何排查

21.如何分析gc日志

22.线上频繁FullGC如何排查

23.讲一下对jvm的理解(太大了 上文内容挑一些吟唱

24.jmm
Java Memory Model Java 内存模型,Java 虚拟机规范中定义的一种抽象内存模型,并非物理内存的实际布局,其核心目标是解决多线程环境下的原子性、可见性、有序性问题,为多线程编程提供内存访问的一致性规则

欢迎佬赐教
上辈子🔪👨放🔥 这辈子十月(底)秋招!!
#发面经攒人品##后端##秋招#
全部评论
好详细谢谢整理分享
点赞 回复 分享
发布于 01-22 21:52 贵州
mark收藏
点赞 回复 分享
发布于 01-03 17:59 江苏
感觉jvm这一块有点绕
点赞 回复 分享
发布于 2025-12-23 17:31 浙江
点赞 回复 分享
发布于 2025-12-10 10:05 河南
第三题答案错了吧,永久代不是非堆内存吗
点赞 回复 分享
发布于 2025-12-08 11:07 江苏

相关推荐

2025-12-27 09:05
内蒙古工业大学 Java
转眼已经实习了7天了,领导比较好,可能是从我身上看到了他年轻时候的样子吧,刚来那天报道完直接让我去租房子,我看了好多,但是怕租金要不回来还有就是得买被子啥的太麻烦了,就不打算租了,住青旅了,一个月1000多,缺点就是每个月1100差不多,但是优点就是我一周叫一个星期的房租,资金周转灵活上周五,领导给我安排了一个活,让我设计程序然后实现找不同啥的,但是能力有限没有实现,不过我每天都在待到8点后蹭公司的加班餐😂,公司挺好的午休2个半小时(实习生是这样的,正式的好像也是),晚上6-8点算加班有餐补和打车。(原话是说我回去要是没事可以在公司学习,公司有餐补)弄了好几天毕业设计了,花钱买了个ai但是挺好用的,每天下班弄毕设,5天从0到数据库到接口文档,再到后端的部分实现,不过昨天突然发现妈的数据库设计错了,两个数据库表关系是多对多,但是我设计成一对多了,真操蛋,下次在从零搭建的话先把数据库关系理清楚,我朋友说。5个公共字段都没有设计,创建人,创建时间,修改时间,修改人,是否删除,另一个朋友说,设计一个日志表。前两天,还在权限分离那块儿纠结,想着。要不要分成teacher和student两种包,和ai聊了之后发现,&nbsp;可以用security,但是听我之前同学说,security实现起来有点麻烦,就改成sa&nbsp;token了(因为我老师和学生都放在一张表上,用户表,有一个权限字段来区分老师和学生)。最担心的事儿可能就是,第1件事儿是转正不了,找不到下家,第2件事就是毕业设计。&nbsp;Monitor特他们都好忙,前天上线到凌晨4点多,然后早上5点30到家😭😭😭😭。转正这件事儿的话,昨天和另一个人聊,他说他的那个朋友,什么都打点好了,但是没有名额😭😭😭,也转正不了,可能比较看命吧,目测了一下,好多实习生,至少6个吧办公室3040多个人。旁边的老哥和我说,他实习了两个月,也申请上公司那个账号,都和他说要转正之后才能申请,然后他就一直干杂活😭😭😭😭。我组长好像是负责那个账号申请的,之前和我组长聊过几次天,送了几次甜水,可能和这些也有关吧,组长不知道多少年程序员了,我门头说,他转正的时候,好像是组长和其他人一起拍板的,说剩下的人都撤退了😭😭😭😭😭😭。现在想来,还是运气最重要,好像实习生,都是通过,就业老师推荐的&nbsp;,,鼠鼠也是,细细想来,那么多九爷和二爷以及本科的都没找到实习,还是得感谢我的老师,这么菜都给我招进来了。想起之前看过的一个短片,就是说。从下面往上面爬,努力是其次的,得有人看到了你的努力,并愿意把你拉上去才行,因为靠你自己是上不去的,每一层都是这样,鼠鼠当时找实习找崩溃了,已经放弃了,真的很感谢基地的就业老师,哎。鼠鼠听另一个实习生说,我这里之前做的大哥,干了好多年,一直没涨工资,然后就走了,10月多走的,哎,工资好像是7300,进去就是巅峰,昨天看到千千发的客户端0基础进厂的抖音,就又开始做白日梦了,突然想明白自己为什么那么容易被骗了,老是觉得自己会是那个最幸运的,总是相信天上会掉馅饼。老是想的太多了,然后又做的太少了。就比如。之前还在想每天背一到八股,结果行动跟不上,总是既要又要。看到别人各种上岸,只看到的结果,却忽略了他们努力的过程,活该人家上岸呀。还是沉不住气,情绪波动太大了,说的话太多了,还是应该居安思危,多反思一下,好久没反思了。总想一口气吃个胖子。
点赞 评论 收藏
分享
评论
15
75
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务