JVM面试必知必会

1,287 阅读5分钟

JVM加载流程和运行时数据区如下图所示:

运行时数据区

方法区

方法区用于存储已经被加载的类信息、常量、静态变量、编译后的代码以及 运行时常量池等。

主要存放一些数据,比如对象实例、数组等。

堆内存会划分为年轻代老年代,年轻代又会分为EdenServivor区,Survivor也会分为FromPlaceToPlace

虚拟机栈

虚拟机栈描述的是JVAV方法执行的内存模型。每个方法被执行的时候同时都会创建一个栈帧,用于存储局部变量表操作数栈动态链接方法出口等信息,不存在垃圾回收问题,只要线程结束,该栈就释放。

本地方法栈

和栈作用类似,但是本地方法栈执行的是native方法。

程序计数器

程序计数器 可以看做是当前线程所执行的行号指示器。

内存泄露和内存溢出

内存泄露的原因
  • 对象是可达的(一直被引用)
  • 对象不会被使用。

这些对象不会被GC所回收,但是却一直占用内存。

内存溢出的原因
  • 内存泄露导致堆栈内存不断增大
  • 大量的jar,class文件加载,装载类的空间不够
  • 操作大量的对象导致堆内存空间用满

GC的方式

  • Minor GC: 年轻代,频率高,速度快
  • Major GC:老年代
  • Full GC:整个堆(年轻代,老年代)

虚拟机堆的年轻代和年老代

  • Eden空间满了之后,会触发一次Minor GC,GC之后还存活的对象将被复制到两个Survivor区域中的一个。假定该Servivor为From区,From区被填满之后,这个区域也要进行GC,GC之后存活的对象会复制到To区,From区清空,因此From和To区必有一区是空的。如此交换15次,最终如果还是存活,将存入老年代。
  • 如果对象的大小大于Eden的二分之一会直接分配在老年代区。如果老年代也分配不下,会做一次老年代的major GC。
  • 如果minor GC后,survivor仍然放不下,则放到老年代。
  • 动态年龄判断。大于等于某个年龄段的对象超过了Servivor空间的一半,则直接进入老年代。

双亲委派模式

当一个类收到加载请求时,它不会先自己去尝试加载,而是委派给父类去完成。

作用:为了解决类载入过程中的安全性问题

  • 假设有一个开发者自己编写了一个名为 java.lang.Object的类,想借此欺骗JVM。现在他要使用自定义 ClassLoader来加载自己编写的 java.lang.Object类。
  • 然而幸运的是,双亲委托模型不会让他成功。因为JVM会优先在 BootstrapClassLoader的路径下找到 java.lang.Object类,并载入它。

类的实例化顺序

  1. 父类静态成员静态初始化块,按代码块中出现的顺序依次执行。
  2. 子类静态成员静态初始化块,按代码块中出现的顺序依次执行。
  3. 父类实例成员实例初始化块,按代码块中出现的顺序依次执行。
  4. 父类构造方法
  5. 子类实例成员实例初始化块,按代码块出现的顺序依次执行。
  6. 子类构造方法。

JVM中一次完整的GC流程是怎样的?

YGC和FGC表示什么?

  • YGC(Young GC): 对新生代堆进行GC。频率比较高,因为大部分对象的存活寿命较短,在新生代里被回收,性能耗费较小。
  • FGC(Full GC): 全堆范围的GC。默认堆空间使用到达80%的时候回触发FGC、

JVM垃圾回收算法有哪些?

我们常用的垃圾回收器一般采用分代收集算法

标记-清除算法

算法分为标记清除两个阶段,首先标记出所有需要回收的对象,在标记完成后统一回收所有标记的对象。

标记压缩算法

首先先标记需要回收的对象,然后让所有存活的对象都向一端移动,最终清理掉端边界以外的内存。

复制算法

将可用内存划分为大小相等的两块,每次用掉其中的一块。当着一块的内存用完了,就将还存活的对象复制到另外一块上面,然后再把已使用的内存空间一次清理掉。

分代收集算法

将JAVA堆分为新生代和老年代,这样就可以根据各个年代的特点采用最适合的收集算法。

常见的垃圾收集器有哪些?

CMS收集器
  • CMS收集器,CMS(Concurrent Mark Sweep)收集器是一种以获取最短回收停顿时间为目标的收集器。
  • CMS收集器需要消耗额外的CPU和内存资源,在CPU和内存资源紧张时,会加重系统负担,
  • CMS无法处理浮动垃圾,CMS的标记-清除算法,会导致大量的空间碎片的产生。
G1收集器

G1(Garbage-First)是一款面向服务端的垃圾收集器,主要针对配备多颗处理器及大容量内存的机器,具备极高概率满足GC停顿的同时,还具备高吞吐量性能特征

Serial收集器
  • Serial收集器,是最古老,最稳定以及效率高串行收集器。
  • 只使用一个线程去回收,可能产生较长的停顿。