点赞再看,养成好习惯!
嗨咯,大家好,明天给大家整顿了一些 JVM 必问的大厂面试题,起因是我的学弟在网上刷了有数面试题,而后前两天信念满满的去阿里面试,没想到在一面的时候被 HR 问到“如何判断一个对象是否存活?(或者 GC 对象的断定办法)”而后卡壳了 …. 我真的想敲死他,这个不是我跟他讲过的要看的知识点吗?
而后学弟弱弱的跟我讲,他刷了网上很多面试题,然而没有看到这道题。过后我的心田一万个草泥马跑过 … 好吧,为了让大家不在 JVM 这个题目上被刷下来,我特意去看了往年所有大厂的面试题,整顿出上面这些 JVM 必问面试题
作为浏览福利小编也把所有的题目 + 解答整顿成了 PDF 文档,如果须要的能够自行下载
JVM 大厂必问面试题【附解答】
1. 内存模型以及分区,须要具体到每个区放什么。
JVM 分为堆区和栈区,还有办法区,初始化的对象放在堆外面,援用放在栈外面,class 类信息常量池(static 常量和 static 变量)等放在办法区 new:
- 办法区:次要是存储类信息,常量池(static 常量和 static 变量),编译后的代码(字节码)等数据
- 堆:初始化的对象,成员变量(那种非 static 的变量),所有的对象实例和数组都要在堆上调配
- 栈:栈的构造是栈帧组成的,调用一个办法就压入一帧,帧下面存储局部变量表,操作数栈,办法进口等信息,局部变量表寄存的是 8 大根底类型加上一个利用类型,所以还是一个指向地址的指针
- 本地办法栈:次要为 Native 办法服务
- 程序计数器:记录以后线程执行的行号
2. 堆外面的分区:Eden,survival(from+ to),老年代,各自的特点。
堆外面分为新生代和老生代(java8 勾销了永恒代,采纳了 Metaspace),新生代蕴含 Eden+Survivor 区,survivor 区外面分为 from 和 to 区,内存回收时,如果用的是复制算法,从 from 复制到 to,当通过一次或者屡次 GC 之后,存活下来的对象会被挪动到老年区,当 JVM 内存不够用的时候,会触发 Full GC,清理 JVM 老年区当新生区满了之后会触发 YGC, 先把存活的对象放到其中一个 Survice 区,而后进行垃圾清理。因为如果仅仅清理须要删除的对象,这样会导致内存碎片,因而个别会把 Eden 进行齐全的清理,而后整顿内存。那么下次 GC 的时候,就会应用下一个 Survive,这样循环应用。如果有特地大的对象,新生代放不下,就会应用老年代的担保,间接放到老年代外面。因为 JVM 认为,个别大对象的存活工夫个别比拟长远。
3. 对象创立办法,对象的内存调配,对象的拜访定位。
new 一个对象
4. GC 的两种断定办法:
- 援用计数法:指的是如果某个中央援用了这个对象就 +1,如果生效了就 -1,当为 0 就会回收然而 JVM 没有用这种形式,因为无奈断定互相循环援用(A 援用 B,B 援用 A)的状况
- 援用链法:通过一种 GC ROOT 的对象(办法区中动态变量援用的对象等 -static 变量)来判断,如果有一条链可能达到 GC ROOT 就阐明,不能到达 GC ROOT 就阐明能够回收
5. SafePoint 是什么
比方 GC 的时候必须要等到 Java 线程都进入到 safepoint 的时候 VMThread 能力开始
执行 GC
- 循环的开端 (避免大循环的时候始终不进入 safepoint,而其余线程在期待它进入 safepoint)
- 办法返回前
- 调用办法的 call 之后
- 抛出异样的地位
6. GC 的三种收集办法:标记革除、标记整顿、复制算法的原理与特点,别离用在什么中央,如果让你优化收集办法,有什么思路?
先标记,标记结束之后再革除,效率不高,会产生碎片
复制算法:分为 8:1 的 Eden 区和 survivor 区,就是下面谈到的 YGC
标记整顿:标记结束之后,让所有存活的对象向一端挪动
7. GC 收集器有哪些?CMS 收集器与 G1 收集器的特点。
并行收集器:串行收集器应用一个独自的线程进行收集,GC 时服务有进展工夫
串行收集器:主要回收中应用多线程来执行
CMS 收集器是基于“标记—革除”算法实现的,通过屡次标记才会被革除
G1 从 整体来看是基于“标记—整顿”算法实现的收集器,从 部分(两个 Region 之间)上来看是基于“复制”算法 实现的
8. Minor GC 与 Full GC 别离在什么时候产生?
新生代内存不够用时候产生 MGC 也叫 YGC,JVM 内存不够的时候产生 FGC
9. 几种罕用的内存调试工具:jmap、jstack、jconsole、jhat
jstack 能够看以后栈的状况,jmap 查看内存,jhat 进行 dump 堆的信息 mat(eclipse 的也要理解一下)
10. 类加载的几个过程:
加载、验证、筹备、解析、初始化。而后是应用和卸载了通过全限定名来加载生成 class 对象到内存中,而后进行验证这个 class 文件,包含文件格式校验、元数据验证,字节码校验等。筹备是对这个对象分配内存。解析是将符号援用转化为间接援用(指针援用),初始化就是开始执行结构器的代码
11.JVM 内存分哪几个区,每个区的作用是什么?
java 虚拟机次要分为以下一个区:
办法区:
- 有时候也成为永恒代,在该区内很少产生垃圾回收,然而并不代表不产生 GC,在这里
进行的 GC 次要是对办法区里的常量池和对类型的卸载 - 办法区次要用来存储已被虚拟机加载的类的信息、常量、动态变量和即时编译器编译后
的代码等数据。 - 该区域是被线程共享的。
- 办法区里有一个运行时常量池,用于寄存动态编译产生的字面量和符号援用。该常量池
具备动态性,也就是说常量并不一定是编译时确定,运行时生成的常量也会存在这个常量
池中。
虚拟机栈:
- 虚拟机栈也就是咱们平时所称的栈内存, 它为 java 办法服务,每个办法在执行的时候都会创立一个栈帧,用于存储局部变量表、操作数栈、动静链接和办法进口等,会创立一个栈帧,用于存储局部变量表、操作数栈、动静链接和办法进口等信息。
- 虚拟机栈是线程公有的,它的生命周期与线程雷同。
- 局部变量表里存储的是根本数据类型、returnAddress 类型(指向一条字节码指令的地址)和对象援用,这个对象援用有可能是指向对象起始地址的一个指针,也有可能是代表对象的句柄或者与对象相关联的地位。局部变量所需的内存空间在编译器间确定
4. 操作数栈的作用次要用来存储运算后果以及运算的操作数,它不同于局部变量表通过索引来拜访,而是压栈和出栈的形式
5. 每个栈帧都蕴含一个指向运行时常量池中该栈帧所属办法的援用,持有这个援用是为了反对办法调用过程中的动静连贯. 动静链接就是将常量池中的符号援用在运行期转化为间接援用。
本地办法栈
本地办法栈和虚拟机栈相似,只不过本地办法栈为 Native 办法服务。堆 java 堆是所有线程所共享的一块内存,在虚拟机启动时创立,简直所有的对象实例都在这里创立,因而该区域常常产生垃圾回收操作。
程序计数器
内存空间小,字节码解释器工作时通过扭转这个计数值能够选取下一条须要执行的字节码指令,分支、循环、跳转、异样解决和线程复原等性能都须要依赖这个计数器实现。该内存区域是惟一一个 java 虚拟机标准没有规定任何 OOM 状况的区域。
感觉本篇文章对你有帮忙的话,记得点赞 + 珍藏 + 转发!!!因为篇幅问题,我就不在这里一一展现了,须要 JVM 必问面试题的敌人,能够自行支付 JVM 大厂必问面试题【附解答】