JVM原理

一、什么是 JVM

JVM 全称为 Java Virtual Machine 即 Java 虚拟机,是在真实计算机上模拟计算机功能的实现。

Java 虚拟机包含了一套字节码指令集、一组寄存器、一个栈、一个垃圾回收堆和一个存储方法域。

二、JRE、JDK、JVM

JRE:java 运行环境,有 JRE 即可运行 java 程序。

JDK:Java Development Kit,编译、调试 Java 程序的开发工具包。

JVM:Java VirtualMachine,java 虚拟机,是 JRE 的一部分。JVM 拥有自己完善的硬件架构,如处理器、堆、栈、寄存器等,还有相应的指令系统。

三、JVM 原理

JVM 将 .java 的源代码文件编译成字节码程序,再通过 JVM 将每一条指令翻译成不同的平台机器码,以实现特定平台运行。

四、JVM 的体系结构

  1. 类加载器 ClassLoader,用来装载 .class 文件
  2. 执行引擎(执行字节码或本地方法)
  3. 运行时数据区(方法区、堆、Java 栈、pc 寄存器、本地方法栈)

五、JVM 运行时数据区

运行时数据区

六、判定“对象已死”的算法

上图中,程序计数器、Java 虚拟机栈、本地方法栈都是线程独享的,其占用的内存也是随线程结束而回收的。而 Java 堆和方法区不同,是线程共享的,几乎存放着所有对象的实例。

GC 需要判断哪些对象能够回收:

  1. 引用计数算法:为对象添加一个引用计数器,每当对象被引用一次,计数器加 1;当引用失效,计数器建议。当计数器为 0 时表示对象可回收。
    • 缺点:难以解决两个对象之间相互引用的问题
  2. 可达性分析算法:通过一系列称之为“GC Roots”的对象作为七点,从这些节点向下搜索,搜索的路径称为引用链,当一个对象到 GC Roots 没有任何引用链相连(即对象到 GC Roots 不可达),则证明此对象已死、可回收。
    • Java 中可作为 GC Roots 的对象包括:虚拟机栈中引用的对象、本地方法栈中的 Native 方法引用的对象、方法区静态属性引用的对象、方法区常量引用的对象

七、JVM 垃圾回收

GC(Garbage Collection):将内存中不再使用的对象进行回收。由于 GC 回收时需要消耗资源和时间,因此在对对象的生命周期特性进行分析后,按新生代、旧生代的方式对对象进行收集,以尽可能的缩短 GC 对应用资源的消耗。

  • 对新生代对象的收集称为 minor GC
  • 对旧生代对象的收集称为 Full GC
  • 程序中调用的 System.gc() 执行的是 Full GC

对于不同的对象引用类型,GC 采用了不同的方法进行回收:

  • 强引用:默认情况下,对象采用的是强引用(即该对象实例没有其他对象引用,才会被回收)
  • 软引用:是 Java 提供的一种比较适合缓存场景的应用(只有在内存不够时才回收)
  • 弱引用:在 GC 时一定会被 GC 回收
  • 虚引用:只是用来得知对象是否被 GC

八、垃圾收集算法

前三种垃圾收集算法

1、标记-清除算法

分为两个阶段:先标记需要回收的对象,在标记完成后统一回收所有被标记的对象。

缺点:

  1. 效率问题:标记和清除过程的效率都不高
  2. 空间问题:标记清除后会产生大量不连续的内存碎片,空间碎片太多会导致分配大对象时无法找到足够的连续内存,而不得不提前触发另一次垃圾回收动作

2、复制算法

为了解决效率问题,出现了“复制”算法。将可用内存按容量划分为大小相等的两块区域,每次只使用其中的一块。当一块内存用完后,将还存活的对象复制到另一块上面,再把刚刚的内存空间一次清理掉。

缺点:

  1. 可用内存为原先的一半
  2. 当对象存活率较高时,会进行频繁的复制操作,效率降低

3、标记-整理算法

标记过程与“标记-清除算法”相同,但是后续不是直接清理对象。而是让所有存活对象向一侧移动,然后直接清理掉端边界以外的内存。

4、分代收集算法(使用最广泛)

分代收集算法

根据对象存活周期,将堆分为新生代和老年代,方法区称为永久代。

新生代中的对象,在每次 GC 时都会有大量对象被回收,少量存活,使用复制算法。

老年代中的对象,因为对象存活率高,没有额外空间进行分配担保,使用标记-清除或标记-整理算法。

5、对象存活周期/GC 回收流程

触发GC回收的流程

九、垃圾收集器

1、Serial 收集器

单线程,在收集时会暂停其它工作线程,直至收集结束。(最基本、历史最久、简单、高效)

仍然是虚拟机在 client 模式下的默认新生代收集器:简单而高效。

2、ParNew 收集器

Serial 的多线程版本,如收集算法、stop the world、对象分配规则、回收策略等,与 Serial 收集器一样。

是许多运行在 Server 模式下的 JVM 首选的 新生代收集器。

3、Parallel Scavenge 收集器

新生代、并行的多线程收集器。

4、Serial Old 收集器

Serial 收集器的老年代版本,单线程,“标记整理”算法,主要给 client 模式使用

5、Parallel Old 收集器

Parallel Scavenge 的老年代版本,多线程,“标记整理”算法

6、CMS 收集器

Concurrent Mark Sweep,以获取最短回收停顿时间为目标的收集器,停顿时间短,用户体验号。

7、G1 收集器

并行与并发,多 CPU、多核、且能与用户线程并发执行;

分代收集;

空间整合:整体上采用标记整理算法,局部上采用复制算法;

可预测的停顿:即收集时间不得超过指定 M 毫秒

十、Java 平台的逻辑结构

java platform

文章转载至:https://juejin.im/post/5b48bf155188251acf6077ad。仅作为自己的笔记使用。

文章作者: koral
文章链接: http://luokaiii.github.io/2020/04/02/后端/java/1.JVM原理/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自