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

下载本文档

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

文档简介

JVM高频面试题及详细真实答案(一线面试版)一、JVM基础核心面试题1、简单说说你对JVM的理解?JVM是Java虚拟机,是运行Java字节码的虚拟机,也是Java跨平台的核心。Java代码编译后不会直接生成机器码,而是生成class字节码文件,由JVM解析、翻译并执行。它本质是一套规范,不同平台有不同的JVM实现,所以一份Java代码可以做到一次编译、到处运行。同时JVM具备内存管理、垃圾回收、即时编译、类加载、异常处理等能力,极大降低了开发者手动管理内存的成本,也是Java高性能、高稳定的基础。2、JVM和JDK、JRE的区别?JDK:Java开发工具包,包含JRE+编译、调试、打包等开发工具,是开发人员使用的环境。JRE:Java运行环境,包含JVM+Java核心类库,只负责运行Java程序,没有开发工具。JVM:Java虚拟机,是JRE的核心部分,只负责加载、执行字节码、管理内存和GC,是程序运行的载体。三者层级:JDK⊃JRE⊃JVM。3、Class文件的作用是什么?为什么不直接编译成机器码?Class文件是Java源代码编译后的字节码文件,是JVM唯一能识别的执行文件。不直接编译机器码主要有两个原因:第一,机器码和操作系统、CPU架构强绑定,直接编译就无法跨平台;第二,字节码是中间层代码,体积更小、通用性更强,JVM可以根据运行环境即时优化,提升程序运行效率。二、JVM内存结构(运行时数据区)1、JVM运行时数据区包含哪些区域?哪些是线程私有?哪些是线程共享?线程私有(随线程创建、销毁,线程间互不干扰):程序计数器:记录当前线程执行的字节码行号,是唯一一个没有内存溢出的区域虚拟机栈:存储栈帧,包含局部变量表、操作数栈、动态链接、方法出口,方法调用和执行都在这里完成本地方法栈:专门为JNI本地方法服务,作用和虚拟机栈类似线程共享(整个JVM进程共享,全局唯一):堆:所有对象和数组的存储区域,也是GC的主要回收区域方法区:存储类信息、常量、静态变量、即时编译后的代码缓存(JDK8后元空间替代永久代)2、程序计数器为什么不会OOM?程序计数器只存储当前线程执行的字节码指令地址,数据量极小且固定,没有扩容、存储大量数据的场景,JVM规范中明确规定该区域不允许出现内存溢出,所以永远不会报OOM。3、虚拟机栈会出现什么异常?栈帧的结构是什么?虚拟机栈主要两种异常:栈深度超过JVM允许最大值,抛出StackOverflowError;栈动态扩展无法申请到足够内存,抛出OOM。栈帧是方法执行的基本单元,每个方法调用都会创建一个栈帧,核心结构:局部变量表、操作数栈、动态链接、方法返回地址、附加信息。4、JDK7和JDK8方法区的区别?永久代和元空间的差异?JDK7及之前使用永久代实现方法区,永久代属于JVM堆内存的一部分,受JVM内存参数限制,容易出现永久代OOM。JDK8彻底废弃永久代,改用元空间实现方法区。元空间直接使用本地操作系统内存,不再占用堆内存,默认没有固定大小限制,极大减少了方法区内存溢出问题,同时类、方法、常量等数据的存储结构也做了优化。三、Java堆内存与对象创建1、堆的内存分区是什么?新生代、老年代比例?堆是GC核心区域,主要分为新生代和老年代。新生代占堆内存1/3,分为Eden区、From幸存区、To幸存区,默认比例8:1:1。绝大多数对象都是朝生夕灭,在新生代创建和回收。老年代占堆内存2/3,存储存活时间久、经过多次GC依然存活的对象,大对象也会直接分配在老年代。2、对象的创建流程?详细说一下1、类加载检查:JVM先判断该类是否已加载、初始化,未加载则先完成类加载过程;2、分配内存:根据对象大小在堆中分配空间,优先Eden区。内存分配有指针碰撞、空闲列表两种方式,取决于堆内存是否规整;3、初始化零值:给对象所有成员变量赋默认零值,保证对象初始化安全;4、设置对象头:存储对象哈希码、GC分代年龄、锁状态、类指针等元数据;5、执行init方法:执行开发者定义的构造方法,完成对象初始化,对象创建完成。3、对象在内存中的布局?分为三部分:对象头、实例数据、对齐填充。对象头:包含MarkWord(哈希码、GC年龄、锁信息)、类型指针(指向对应类的元数据),数组还会存储数组长度;实例数据:存储对象的成员变量数据;对齐填充:JVM要求对象内存大小必须是8字节的整数倍,不足部分用占位符填充,无实际作用。4、逃逸分析的作用是什么?栈上分配了解吗?逃逸分析是JVM的编译优化手段,用来判断对象是否会逃逸出当前方法。如果对象只在当前方法内使用,不会被外部引用、不会逃逸,JVM就会优化将对象分配在虚拟机栈上,而非堆中。方法执行结束后,栈内存直接释放,无需GC回收,大幅减少堆内存压力和GC次数,提升程序性能。四、垃圾回收GC核心面试题1、JVM如何判断对象是垃圾?引用计数和可达性分析的区别?引用计数法:给对象添加引用计数器,有引用则+1,失效则-1,计数器为0即为垃圾。缺点是无法解决循环引用问题,主流JVM不再使用。可达性分析法:JVM核心判断方式。以GCRoots作为起始节点,遍历引用链,无法被遍历到的对象即为垃圾。可以完美解决循环引用问题。常见GCRoots:虚拟机栈中局部变量引用的对象、方法区静态变量/常量引用的对象、本地方法栈JNI引用的对象、活跃线程对象。2、Java中的引用类型有几种?分别场景?四种引用,强度从高到低:强引用:默认引用方式,只要有强引用,GC永远不会回收,是日常开发最常用的引用;软引用:内存充足不回收,内存不足触发OOM前会回收,适合做缓存(图片缓存、临时数据缓存);弱引用:只要触发GC就会被回收,生命周期极短,适合防止内存泄漏,比如ThreadLocal、WeakHashMap;虚引用:最弱的引用,无实际引用作用,仅用于记录对象回收的通知,主要用于堆外内存回收监控。3、GC的分类?MinorGC、MajorGC、FullGC区别?MinorGC:新生代垃圾回收,频率高、速度快,触发时机是Eden区内存满。采用复制算法,停顿时间短,对程序影响小。MajorGC:老年代垃圾回收,频率低、速度慢,通常伴随MinorGC。老年代空间不足、对象晋升过多时触发。FullGC:整堆回收,回收新生代、老年代、元空间,开销最大、停顿最长。常见触发场景:手动调用System.gc()、老年代严重不足、MinorGC后晋升失败、元空间内存不足。生产环境要尽量避免FullGC。4、常见GC算法有哪些?各自优缺点?标记清除:先标记垃圾对象,再统一清除。优点:简单易实现;缺点:产生大量内存碎片,分配大对象容易失败。标记整理:标记垃圾后,将存活对象向一端移动,整理内存。优点:无内存碎片;缺点:移动对象成本高,速度慢,多用于老年代。复制算法:将内存分为两块,一块使用,一块空闲,存活对象复制到空闲区,清空原区域。优点:无碎片、速度快;缺点:内存利用率低,适合对象存活率低的新生代。5、主流垃圾收集器区别?G1、CMS、ZGC核心特点CMS(并发标记清除):专注低停顿,并发回收,用户线程和GC线程并行执行。缺点:存在内存碎片、浮动垃圾,无法处理浮动垃圾导致并发失败,触发FullGC,JDK14后被废弃。适合响应速度优先的Web服务。G1:分区式收集器,将堆划分为多个大小相等的Region,可精准控制停顿时间,兼顾吞吐量和低延迟,默认JDK9+默认收集器。可以优先回收垃圾最多的分区,回收效率高,适合大内存服务器。ZGC:超低延迟收集器,JDK11推出、JDK15正式使用。支持TB级内存,停顿时间控制在十毫秒级,几乎不影响业务,适合对延迟要求极高的高并发服务。五、类加载机制1、类加载的全过程?分为五个阶段:加载、验证、准备、解析、初始化。加载:读取class字节码文件,加载到内存,生成Class对象;验证:校验字节码合法性、安全性,防止恶意、错误字节码;准备:给静态变量分配内存并赋默认零值;解析:将代码中的符号引用替换为直接内存引用;初始化:执行静态代码块、静态变量赋值,是类加载最后一步,也是主动加载的触发点。2、双亲委派模型是什么?工作流程和意义?双亲委派是类加载器的加载规则:当一个类需要加载时,优先交给父类加载器处理,父类无法加载再由子类加载,自上而下委派,自下而上加载。加载器层级:启动类加载器→扩展类加载器→应用类加载器→自定义类加载器。核心意义:保证核心类库安全,防止开发者自定义类覆盖JDK核心类,保证类的唯一性和安全性。3、什么是打破双亲委派?常见场景?打破双亲委派就是不遵循父类优先加载的规则,由子类加载器优先加载类。常见场景:SPI机制、Tomcat容器、热部署、模块化开发。比如Tomcat需要加载不同项目的同名类,必须打破双亲委派,实现项目类隔离。六、JVM调优与线上故障实战1、线上频繁FullGC如何排查?1、查看GC日志,判断FullGC触发原因,是内存不足、晋升失败还是手动GC;2、使用jmap导出堆快照,用MAT分析大对象、内存泄漏对象;3、排查是否存在大量临时大对象、集合未清空、静态集合无限扩容;4、检查JVM参数,查看新生代、老年代比例是否合理,是否内存分配过小;5、排查代码问题,比如循环创建对象、资源未释放、线程池堆积对象等。2、OOM常见场景及解决方案?堆内存溢出:大量对象无法回收、内存泄漏。解决:排查泄漏代码、优化对象创建、调整堆内存大小;栈内存溢出:递归过深、方法嵌套过多。解决:优化递归逻辑、调整栈大小;元空间溢出:动态生成大量类、热部署频繁加载类。解决:调整元空间大小、优化类加载逻辑;直接内存溢出:NIO堆外内存未释放。解决:手动释放堆外内存、优化NIO资源关闭逻辑。3、常用JVM调优命令有哪些?作用?jps:查看Java进程PID;jstat:实时查看GC统计信息,监控新生代、老年代GC次数和耗时;jmap:查看堆内存快照、对象统计,导出dump文件;jstack:查看线程堆栈,排查死锁、线程阻塞、线程耗尽问题;jhat:分析堆快照文件。4、如何减少GC频率、优化GC性能?1、避免循环创建对象,优先使用局部变量,利用栈上分配优化;2、大对象提前复用,使用对象池、线程池,减少频繁创建销毁;3、合理设置堆内存大小,避免内存过小频繁GC,也避免过大导致单次GC耗时变长;4、优先使用G1/ZGC低延迟收集器,适配线上高并发场景;5、及时清空集合、解除无用引用,避免内存泄漏导致GC堆积。七、进阶高频面试题1、对象晋升老年代的条件?1、对象GC分代年龄达到阈值(默认15岁),晋升老年代;2、新生代幸存区放不下存活对象,直接晋升老年代;3、大对象直接分配老年代,避免新生代复制开销;4、MinorGC后存活对象过多,触发批量晋升。2、什么是内存泄漏?和内存溢出的区别?内存泄漏:程序中无用对象持续持有引用,GC无法回收,内存被长期占用,是过程。比如静态集合存储对象不清理、Th

温馨提示

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

评论

0/150

提交评论