一文带你学会JVM运行核心运行流程

2,052 阅读3分钟

阅读更多精彩文章,欢迎关注微信公众号:深夜程猿

从类的加载说起

在谈JVM核心运行流程之前,我们先说下java的类加载机制。

我们知道,java的类加载机制采取的是双亲委派机制。

所谓双亲委派机制,也就是说在加载一个类的时候,先一步一步往上传递由最顶层的类加载器加载,加载不到就交给直接下一层类加载器加载,一步一步往下传递,直到某一个类加载器加载到类才结束加载。如果所有的类加载器都不能加载到该类,那么就会抛出类找不到的异常

在java虚拟机规范中,定义了三种类加载器,分别是:

  • 引导类加载器:BootstrapClassLoader

最顶层的类加载器

  • 扩展类加载器:ExtensionClassLoader

BootstrapClassLoader加载器的子类

  • 应用类加载器:ApplicationClassLoader

扩展类加载器的子类

此外我们还可以自定义自己的类加载器。

一个类从加载到使用,其生命周期有七个阶段:

  • 加载阶段

加载.class文件到JVM内存

  • 验证阶段

根据JVM规范验证.class是否合法

  • 准备阶段

主要是给类分配内存空间,这个阶段会计算出类需要占用多大的内存空间

  • 解析阶段

主要是把符号引用改为直接引用

  • 初始化阶段

真正的为类进行初始化,包括静态代码块的执行,类的全局变量的赋值操作

  • 使用阶段

经过类的初始化阶段,类就可以被JVM中的线程使用了

  • 卸载

有些类不再被使用或者由于内存紧张,短期内不会使用到的类就会从JVM内存中移除,等到下一次需要它们的时候再加载进来

上面和大家说说了类的加载各个阶段,这里不深入讨论每一个阶段的细节,大家有个整体的流程印象就可以了。

JVM的内存模型

.class文件加载到JVM内存中,需要对类的不同的东西进行分门别类的存储起来,方便管理和使用。在JVM内存中,主要分出四大块内存区域来存储和管理类:

  • 方法区

存储类的信息和静态常量

  • 堆内存

用来存储类的对象

  • 程序计数器

这是线程独立的一个内存块,用来记录在线程中程序指令执行的位置

  • 虚拟机栈

这也是线程独立的,该内存区域会维护一个方法栈,每调用一次方法都会往方法栈加入一个方法调用记录,方法执行完毕再出栈。该内存区域还会存储方法的局部变量

总的来说,每一个java应用都对应这一个JVM进程。在JVM进程中,需要使用到类的时候,就会把类加载到JVM进程中。经过多个阶段加载进来的类,JVM会分门别类在不同的内存区域存储类的信息,方便后续管理和使用。

一张图总结JVM核心运行流程

总的来说,JVM的核心运行流程实际就是类被加载到JVM进程的过程,以及在JVM内存中对类的存储和管理过程。下面用一张图给大家总结以下JVM的核心运行流程。

JVM核心流程