JVM高频面试题及详细答案(实战通俗版)_第1页
JVM高频面试题及详细答案(实战通俗版)_第2页
JVM高频面试题及详细答案(实战通俗版)_第3页
JVM高频面试题及详细答案(实战通俗版)_第4页
JVM高频面试题及详细答案(实战通俗版)_第5页
已阅读5页,还剩4页未读, 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

JVM高频面试题及详细答案(实战通俗版)一、JVM基础核心面试题1、简单说说你对JVM的理解?JVM就是Java虚拟机,是运行Java字节码的虚拟机,也是Java跨平台的核心。我们写的Java源码,编译后会生成.class字节码文件,JVM负责解析、执行这些字节码。它不直接识别Java代码,只识别字节码,所以实现了“一次编译,到处运行”。不同系统有对应版本的JVM,屏蔽了底层操作系统的差异。核心作用主要三点:一是内存管理,自动分配和回收内存,避免手动操作内存的风险;二是字节码执行,通过解释+即时编译的方式运行代码;三是安全校验,对字节码进行合法性校验,防止恶意代码和非法操作。2、JDK、JRE、JVM的区别与联系?JVM:Java虚拟机,是Java程序运行的核心环境,只负责运行字节码,没有编译、开发工具,是JRE的核心组成部分。JRE:Java运行环境,包含JVM+Java核心类库(rt.jar等),只用于运行Java程序,普通用户部署项目只需要装JRE。JDK:Java开发工具包,包含JRE+开发编译工具(javac、java、jar等),开发人员必须安装JDK,用来编写、编译、调试代码。包含关系:JDK⊃JRE⊃JVM。3、Java程序的执行流程是什么?1、开发者编写.java源代码文件;2、通过javac编译器编译源代码,生成对应的.class字节码文件;3、JVM的类加载器加载.class字节码文件到内存;4、字节码校验器校验字节码的合法性、安全性;5、JVM通过解释器逐行解释执行,热点代码会被即时编译器编译成机器码;6、程序运行过程中,垃圾回收器自动回收无用对象内存,程序结束释放资源。二、JVM内存结构(运行时数据区)1、JVM运行时数据区包含哪些区域?哪些是线程私有?哪些是线程共享?JVM运行时数据区总共分为5个区域,划分核心依据是线程是否隔离。线程私有(随线程创建而创建,线程销毁而销毁):1、程序计数器:当前线程执行的字节码行号指示器,是唯一一个没有OOM的内存区域;2、虚拟机栈:也叫Java栈,存储栈帧,包含局部变量表、操作数栈、动态链接、方法出口,方法调用和执行都靠它;3、本地方法栈:作用和虚拟机栈类似,专门为JVM调用的native本地方法服务。线程共享(全局唯一,所有线程共用):1、堆内存:唯一存放对象实例和数组的区域,也是GC回收的主要区域;2、方法区:存储类信息、常量、静态变量、即时编译后的代码缓存,JDK8之后元空间替代永久代。2、详细说说虚拟机栈和栈帧?栈溢出的原因?虚拟机栈的最小单位是栈帧,每调用一个方法,就会创建一个栈帧,压入虚拟机栈;方法执行结束,栈帧弹出销毁。栈帧核心组成:1、局部变量表:存放方法的局部变量、基本数据类型、对象引用地址,编译期就确定大小;2、操作数栈:执行代码时的临时数据存储、运算、赋值都在这里完成;3、动态链接:将符号引用转化为直接引用;4、方法返回地址:记录方法执行结束后回到调用位置。栈溢出(StackOverflowError)常见原因:1、递归调用没有终止条件,无限创建栈帧,栈内存占满;2、方法嵌套调用层级过深,超出JVM默认栈大小;注意:虚拟机栈的OOM很少见,主流是栈溢出错误。3、JDK7和JDK8方法区的区别?永久代和元空间的差异?JDK1.7及之前:永久代方法区的落地实现是永久代,使用JVM堆内存的一部分,有固定大小限制。容易出现永久代OOM,因为类、方法、常量过多会占满永久代,而且很难精准调优。JDK1.8及之后:元空间(Metaspace)彻底废弃永久代,改用元空间,直接使用本地物理内存,不再占用堆内存。默认情况下没有固定上限,只受限于服务器物理内存,极大减少了方法区OOM问题。核心区别:永久代属于JVM堆内存,元空间属于本地内存;永久代容易OOM,元空间基本不会。4、对象的创建过程?对象在内存中的布局?对象创建流程:1、类加载检查:判断类是否已加载、初始化,没有则先完成类加载;2、分配内存:JVM优先在新生代Eden区分配内存,通过指针碰撞或空闲列表分配;3、内存初始化零值:保证对象的成员变量有默认初始值;4、设置对象头:记录对象的哈希码、锁状态、GC分代年龄、类指针等信息;5、执行构造方法:初始化成员变量,完成对象创建。对象内存布局(堆中):1、对象头:占12字节(64位无压缩),包含MarkWord、类元数据指针;2、实例数据:对象的成员变量、属性数据;3、对齐填充:JVM要求对象内存大小必须是8的整数倍,不足则补位填充。三、类加载机制1、类加载的全过程分为哪几个阶段?整体分为5个核心阶段,全程由类加载器完成:1、加载:读取.class字节码文件,加载到内存,生成对应的Class对象;2、验证:校验字节码格式、语义、安全性,确保没有非法、恶意代码;3、准备:为类的静态变量分配内存,赋予默认初始值,不会赋值自定义值;4、解析:把代码中的符号引用,替换为内存地址的直接引用;5、初始化:执行静态代码块、给静态变量赋自定义初始值,是类加载最后一步。2、双亲委派模型是什么?工作流程和好处?双亲委派工作流程:1、自定义类加载器收到类加载请求,不会自己先加载,向上委托给父类加载器;2、父类加载器继续向上委托,一直委托到顶层启动类加载器;3、顶层加载器无法加载该类时,再向下逐层由子类加载器加载;简单说:向上委托,向下加载。核心好处:1、保证类的安全性:防止开发者自定义覆盖核心类(比如java.lang.String),避免安全漏洞;2、保证类的唯一性:同一个类只会被加载一次,避免重复加载导致类冲突。3、JVM的类加载器有哪些?层级关系?从上到下层级依次为:1、启动类加载器(Bootstrap):顶层加载器,C++编写,加载JDK核心底层类,比如java.lang、java.util包下的类;2、扩展类加载器(Extension):加载JDK扩展目录下的jar包和类;3、应用类加载器(App):系统默认加载器,加载项目classpath下的自定义类、第三方依赖包;4、自定义类加载器:开发者自己实现的加载器,适用于热部署、模块隔离、加密加载等场景。4、什么是类的主动引用和被动引用?类初始化的触发条件?主动引用(触发类初始化):1、new实例化对象、调用类的静态方法、访问静态变量;2、使用反射方式调用类;3、初始化子类时,会先初始化父类;4、程序启动的主类。被动引用(不触发初始化):1、定义类数组、声明类引用;2、访问编译期常量(final静态常量);3、子类引用父类静态变量,只会初始化父类,不会初始化子类。四、垃圾回收GC核心1、JVM为什么不用手动回收内存?GC的核心作用?Java摒弃了手动申请和释放内存的模式,由JVM自动垃圾回收。手动回收容易出现内存泄漏、野指针、重复释放等问题,极大增加开发风险。GC核心就是自动识别堆中无效对象,清理空闲内存,整理内存碎片,保证内存高效利用,让开发者专注业务代码。2、如何判断对象是垃圾?引用计数法和可达性分析?引用计数法:给每个对象加引用计数器,被引用+1,失效-1,计数器为0则判定为垃圾。弊端是无法解决循环引用问题,主流JVM已经废弃。可达性分析(JVM默认):以GC根对象为起点遍历,能遍历到的对象都是存活对象,没有遍历到的就是垃圾对象。常见GC根:虚拟机栈局部变量对象、本地方法栈对象、方法区静态变量、常量引用对象。3、Java的引用类型有哪些?区别和使用场景?1、强引用:默认引用,只要有强引用指向,GC永远不会回收,OOM也不会回收。普通对象赋值就是强引用,日常开发最常用。2、软引用:内存充足不回收,内存不足触发GC时回收。适合做缓存(图片缓存、临时数据缓存),避免内存溢出。3、弱引用:只要触发GC,无论内存是否充足,都会被回收。适合非必须缓存,比如ThreadLocal的key、缓存临时数据。4、虚引用:最弱的引用,几乎无实际作用,仅用于监控对象回收状态,配合回收队列使用。4、GC的分类?MinorGC、MajorGC、FullGC区别?MinorGC(新生代GC):只清理新生代Eden、Survivor区,触发频率高、速度快、耗时短,不会影响老年代。大多数对象朝生夕死,新生代回收效率极高。MajorGC(老年代GC):只清理老年代,触发频率低,速度慢、耗时久,通常伴随MinorGC。FullGC(整堆GC):清理整个堆内存(新生代+老年代+元空间),耗时最长、STW时间最长,线上项目要尽量避免频繁FullGC。频繁FullGC常见原因:老年代内存不足、元空间溢出、显式调用System.gc、MinorGC后大量对象晋升老年代。5、常见垃圾回收算法原理及优缺点?1、标记清除算法流程:先标记垃圾对象,再统一清除垃圾。优点:简单易实现;缺点:产生大量内存碎片,大对象无法分配内存,触发GC。2、复制算法流程:将存活对象复制到空闲内存区,清空原内存。优点:无内存碎片、效率高;缺点:需要双倍内存空间,内存利用率低。新生代默认使用复制算法。3、标记整理算法流程:标记垃圾对象,将存活对象向一端移动,清理末端垃圾。优点:无内存碎片、内存利用率高;缺点:移动对象成本高,速度慢。老年代默认使用标记整理。6、新生代分区原理?Eden、S0、S1比例及作用?新生代分为1个Eden区、2个Survivor区(S0、S1),默认比例8:1:1。1、新对象优先在Eden区分配,Eden满了触发MinorGC;2、GC时Eden存活对象复制到空闲的Survivor区;3、两个Survivor始终一个空闲、一个存储存活对象,来回轮换;4、对象在Survivor区熬过15次GC(默认),晋升到老年代。设置两个Survivor的核心目的:避免频繁复制对象,减少内存碎片,保证新生代回收效率。7、常用垃圾收集器对比?G1、ZGC核心特点?Serial收集器:单线程收集器,回收时暂停所有用户线程,适合客户端、小内存项目,现在基本不用。Parallel收集器:多线程并行回收,侧重吞吐量优先,适合后台计算型项目,追求高吞吐量、低CPU闲置。CMS收集器:并发低停顿收集器,侧重低延迟,用户线程和GC线程并发执行,停顿时间短。缺点是内存碎片多、CPU占用高,JDK14之后废弃。G1收集器(JDK9默认):分区式收集器,将整个堆划分为多个大小相等的Region,可单独回收新生代、老年代区域。兼顾吞吐量和低延迟,支持可控停顿时间,适合中大型项目。核心优势是解决CMS内存碎片问题,GC停顿时间可控。ZGC收集器(JDK11+):超低延迟收集器,停顿时间毫秒级,支持超大堆内存,几乎不随堆内存大小影响GC耗时,是目前线上高性能、低延迟项目的首选。五、JVM调优与故障排查1、常见JVM参数有哪些?堆、新生代、元空间核心参数?堆内存参数-Xms:初始堆内存,线上一般和最大堆设置相同,避免频繁扩容缩容;-Xmx:最大堆内存;新生代参数-Xmn:设置新生代整体大小;-XX:SurvivorRatio:设置Eden和Survivor比例;元空间参数-XX:MetaspaceSize:初始元空间大小;-XX:MaxMetaspaceSize:最大元空间大小,防止元空间无限膨胀;GC日志参数-XX:+PrintGCDetails:打印详细GC日志;-Xloggc:日志路径:输出GC日志到指定文件。2、OOM常见场景及排查思路?常见OOM类型:1、堆内存溢出:创建大量大对象、集合无限累加、内存泄漏,堆内存占满;2、元空间溢出:动态生成大量类、反射、动态代理,类数量过多;3、栈溢出:递归死循环、方法嵌套过深;4、直接内存溢出:NIO、Netty使用直接内存未释放。排查步骤:1、查看报错日志,定位OOM类型;2、开启堆dump文件,故障时自动导出内存快照;3、使用MAT、JProfiler分析dump文件,找出大对象、常驻内存对象;4、排查代码是否存在集合未清空、静态集合滥用、循环创建对象、资源未释放等问题;5、适当调整JVM内存参数,优化GC策略。3、线上频繁FullGC如何排查和解决?排查流程:1、查看GC日志,确认FullGC的频率、耗时、内存变化;2、查看老年代内存占用,判断是内存泄漏还是内存参数不足;3、排查是否有手动调用System.gc的代码;4、排查大对象频繁创建、动态类生成、线程池资源不释放等问题。解决方案:1、修复内存泄漏代码,及时释放无用对象、清空集合;2、优化JVM参数,合理分配新生代、老年代内存;3、更换合适的垃圾收集器,高并发低延迟场景使用G1/ZGC;4、禁止手动调用System.gc。4、STW是什么?哪些GC会触发STW?STW即暂停所有用户业务线程,只保留GC线程工作,暂停期间所有业务代码停止执行,是GC卡顿的核心原因。所有GC都会触发STW,只是停顿时间不同:1、MinorGC:STW时间极短,几乎无感知;2、CMS:大部分阶段并发,仅初始标记、重新标记触发短暂STW;3、FullGC:全程STW,停顿时间最长,对线上业务影响最大。六、经典面试压轴题1、对象创建过程中,优先分配Eden还是老年代?什么情况直接进入老年代?绝大多数普通对象优先分配在新生代Eden区。三种情况对象直接进入老年代:1、超大对象:超过新生代最大分配阈值的大数组、大对象,直接在老年代分配,避免新生代复制损耗;2、长期存活对象:在Survivor区熬过15次GC,晋升老年代;3、动态年龄判断:Survivor区相同年龄对象总大小超过Survivor空间一半,大于等于该年龄的对象全部晋升老年代。2、什么是内存泄漏?Java中常见内存泄漏场景?内存泄漏就是对象已经失效,业务不再使用,但仍然存在有效引用

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论