<面试必过系列>2021最新JVM大厂必问面试题【附解答】

点赞再看,养成好习惯!java

嗨咯,你们好,今天给你们整理了一些JVM必问的大厂面试题,原由是个人学弟在网上刷了无数面试题,而后前两天信心满满的去阿里面试,没想到在一面的时候被HR问到 “如何判断一个对象是否存活?(或者 GC 对象的断定方法)” 而后卡壳了…我真的想敲死他,这个不是我跟他讲过的要看的知识点吗?web

而后学弟弱弱的跟我讲,他刷了网上不少面试题,可是没有看到这道题。当时个人心里一万个草泥马跑过…好吧,为了让你们不在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 一个对象eclipse

4. GC 的两种断定方法:

  • 引用计数法:指的是若是某个地方引用了这个对象就+1,若是失效了就-1,当为 0 就会回收可是 JVM 没有用这种方式,由于没法断定相互循环引用(A 引用 B,B 引用 A)的状况
  • 引用链法: 经过一种 GC ROOT 的对象(方法区中静态变量引用的对象等-static 变量)来判断,若是有一条链可以到达 GC ROOT 就说明,不能到达 GC ROOT 就说明能够回收

5. SafePoint 是什么

好比 GC 的时候必需要等到 Java 线程都进入到 safepoint 的时候 VMThread 才能开始
执行 GCsvg

  1. 循环的末尾 (防止大循环的时候一直不进入 safepoint,而其余线程在等待它进入safepoint)工具

  2. 方法返回前优化

  3. 调用方法的 call 以后

  4. 抛出异常的位置

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 虚拟机主要分为如下一个区:

方法区:

  1. 有时候也成为永久代,在该区内不多发生垃圾回收,可是并不表明不发生 GC,在这里
    进行的 GC 主要是对方法区里的常量池和对类型的卸载

  2. 方法区主要用来存储已被虚拟机加载的类的信息、常量、静态变量和即时编译器编译后
    的代码等数据。

  3. 该区域是被线程共享的。

  4. 方法区里有一个运行时常量池,用于存放静态编译产生的字面量和符号引用。该常量池
    具备动态性,也就是说常量并不必定是编译时肯定,运行时生成的常量也会存在这个常量
    池中。

虚拟机栈:

  1. 虚拟机栈也就是咱们日常所称的栈内存,它为 java 方法服务,每一个方法在执行的时候都会建立一个栈帧,用于存储局部变量表、操做数栈、动态连接和方法出口等,会建立一个栈帧,用于存储局部变量表、操做数栈、动态连接和方法出口等信息。

  2. 虚拟机栈是线程私有的,它的生命周期与线程相同。

  3. 局部变量表里存储的是基本数据类型、returnAddress 类型(指向一条字节码指令的地址)和对象引用,这个对象引用有多是指向对象起始地址的一个指针,也有多是表明对象的句柄或者与对象相关联的位置。局部变量所需的内存空间在编译器间肯定

4.操做数栈的做用主要用来存储运算结果以及运算的操做数,它不一样于局部变量表经过索引来访问,而是压栈和出栈的方式

5.每一个栈帧都包含一个指向运行时常量池中该栈帧所属方法的引用,持有这个引用是为了支持方法调用过程当中的动态链接.动态连接就是将常量池中的符号引用在运行期转化为直接引用。

本地方法栈

本地方法栈和虚拟机栈相似,只不过本地方法栈为 Native 方法服务。堆java 堆是全部线程所共享的一块内存,在虚拟机启动时建立,几乎全部的对象实例都在这里建立,所以该区域常常发生垃圾回收操做。

程序计数器

内存空间小,字节码解释器工做时经过改变这个计数值能够选取下一条须要执行的字节码指令,分支、循环、跳转、异常处理和线程恢复等功能都须要依赖这个计数器完成。该内存区域是惟一一个 java 虚拟机规范没有规定任何 OOM 状况的区域。

以为本篇文章对你有帮助的话,记得点赞+收藏+转发!!!因为篇幅问题,我就不在这里一一展现了,须要JVM必问面试题的朋友,能够查看下图