32个java面试考点:深入浅出JVM

课程链接:https://kaiwu.lagou.com/course/courseInfo.htm?courseId=1&sid=3-PC_banner-0

知识点汇总

一、JVM内存模型

:也叫方法栈,存储局部变量表,动态链接,方法出口等信息,调用方法执行入栈,方法返回执行出栈。

本地方法栈:与方法栈类似,区别是执行native方法使用的是本地方法栈,执行java方法使用的是方法栈。

(注:native方法即使用native关键字修饰的java方法,目的在于与操作系统进行交互,调用操作系统语言程序。)

程序计数器:保存当前线程所保存的字节码位置,每个线程工作时都有一个独立的计数器,程序计数器只为java方法服务,执行native方法时,程序计数器为空。

:jvm内存管理中最大的一块,用于存放对象的实例,当对空间不足时,会抛出OOM异常(java.lang.OutOfMemoryError),jvm把堆内存进行分代管理,由垃圾回收器进行对象的回收管理。

方法区:又叫非堆区,用于存储已被虚拟机加载的类信息、常亮、静态变量、编译器优化后的代码等数据,jdk1.7的永久代和1.8的materspace都是方法区的一种实现。

栈、本地方法栈、程序计数器是线程独占的。

堆、方法区是线程共享的。

二、Java内存模型(JMM)

JMM需要保证原子性、可见性、有序性,通过以下四种方式:

1、基本数据类型读或写(long、double除外):是原子性的。

2、synchronized:通过java的两个高级字节码指令monitorenter和monitorexit来保证原子性,

3、volatile

  • 可见性保证:强制变量的赋值会刷新回主内存,强制变量的读取会从主内存中重新加载,保证不同的线程总是能看到该变量的最新值。
  • 有序性保证:通过指令重排序保证变量读写的有序性。

4、happens-bofore原则

  • 程序顺序原则:一个线程内必须保证语义串行性;
  • 锁规则:同一把锁的解锁必须发生在再次枷锁之前;
  • 传递性规则、线程的启动、中断、终止规则等。

三、类的加载与卸载

深绿色表示加载过程,浅绿色表示生命周期。

加载:通过类的完全限定名找到字节码文件,通过字节码文件创建class对象。

验证:图中始终验证方法。

准备:为static修饰的变量分配内存,初始值0或者null。(final不分配,因为在编译时已经分配)

解析:图中。

初始化:看图中解释,若类的父类没有初始化,则先初始化父类的静态块和静态变量,只有对类的主动使用时才会初始化。

  • 初始化的出发条件:创建类实例、访问类静态变量或者静态方法、class.forName()发射加载、某个子类被初始化。

使用:实例化。

卸载:java前三种类加载器的加载的类不会被卸载,用户自定义类加载器加载的类才会被卸载。

四、类加载器与加载模式

类加载器:启动类加载器、扩展类加载器、应用/系统加载器、用户自定义加载器。

双亲委派模式好处

  1. 避免类的重复加载;
  2. 防止java系统类被篡改。

五、内存分代回收

年轻代:大部分对象会在Eden区生成,Eden区满时,会在s1和s2中交替保存,达到一定次数对象会晋升到老年代。

老年代:存储由年轻代晋升到老年代存储时间较长的内存对象。

永久代:主要保存类信息等内容。(这里只是一种划分方式,并不是特指1.7 PermGen/1.8 Metaspace)

六、垃圾回收算法

判断算法:

  1. 引用计数法
  2. 可达性分析算法

清除算法:

  1. 引用计数算法:通过对象被引用的次数确定对象是否被使用,缺点是无法解决循环引用的问题。
  2. 复制算法:分为from块和to块,开始在from块,回收时将from块存活的对象复制到to块,将from块清空,to块变from块,from块变to块,缺点是内存使用率较低。
  3. 标记清除算法:分为标记对象和标记不在使用的对象两个阶段,缺点是会产生内存碎片。
  4. 标记整理算法:与标记清除算法相同,不过在清楚后会进行内存整理。
  5. 分代回收算法:当前的商业虚拟机的垃圾收集都是采用“分代收集”(Generational Collection)算法,这种算法并没有什么新的思想,只是根据对象存活周期的不同将内存划分为几块。一般是把堆划分为新生代和老年代,这样就可以根据各个年代的特点采用最适合的收集算法。在新生代中,每次垃圾收集时都发现有大批对象死去,只有少量存活,那就采用复制算法,只需要付出少量存活对象的复制成本就可以完成收集。而老年代中因为对象存活率高、没有额外空间对它进行分配担保,就必须使用“标记-清理”或者“标记-整理”算法来进行回收

jvm提供的年轻代回收算法属于复制算法,CMS、G1,ZGC属于标记清除算法。

6.1 CMS算法

CMS是标记清除算法,JDK1.7之前的默认垃圾回收算法,并发收集,停顿小。

  1. 初始标记(STW):标记GC roots直接可达的对象。
  2. 并发标记:GC线程应用线程并发进行,主要标记可达的对象。
  3. 重新标记(STW):停顿时间比并发标记小很多,比初始标记稍长,主要是从新扫描并标记。
  4. 并发清理:并发执行,开始清理未标记的对象。
  5. 并发重置:为下一次GC充值相关数据。

6.2 G1算法

G1算法JDK1.9之后默认回收算法,特点是保持高回收率的同时,减少停顿。

  • 年轻代回收:采用复制算法。
  • 老年代回收:采用标记清除算法,同时也会回收年轻代。

G1可以通过设置JVM参数设置rejion(区)的大小,范围是1~32M,还可以设置期望的最大停顿时间。

6.3 ZGC算法

ZGC针对大内存的回收,可以控制在10ms以内的停顿。

  1. 着色指针
  2. 读屏障
  3. 并发处理
  4. 基于Rejion
  5. 内存压缩(整理)

ZGC GC过程:

面试考察点与真题

1、JVM内存模型、JMM内存模型

2、类加载过程、双亲委派机制

3、原子性、可见性、有序性的保证机制

4、G1适合对最大延迟有要求的场合,ZGC适合64位对大内存有要求的场合

5、垃圾回收的并发数,偏向锁的设置

1、栈上分配释放压力,如何编写适合内联优化的代码

2、经常fullGC的问题,内存泄漏问题

3、

4、

1、见上

2、年轻代晋升、老年代空间不足、永久代空间不足

3、见上

4、见上

5、见上

6、见上

7、强制主内存读写同步,防止指令重排序

10、

强引用:不会被GC回收

弱引用:每次GC都会被回收

虚引用:必须和引用兑现联合使用,跟总一个对象被垃圾回收的过程

软引用:空间不足会被GC回收

11、

JMC:飞行计数器

MAT:堆分析工具

JStack:线程分析工具

猜你喜欢

转载自blog.csdn.net/Mr_BJL/article/details/88071222