网站首页 > 技术文章 正文
请关注码神手记,更多干货持续输出中。
JVM规范系列断断续续已经写了半年,最近结合一些小伙伴们的建议进行了一次复盘,决定在写法上进行一些演进优化:
前面的文章都是在讲解JVM规范的局部内容,这次我们从宏观视角梳理JVM的生命周期,话不多说,进入正题!
启动
一切始于main方法!JVM通过触发一个初始类的加载而启动,这个初始类中应当包含main方法。JVM会调用main方法从而驱动后续所有的执行。在JVM的实现中,可以通过命令行参数指定初始类,也可以通过设置一个类加载器来指定初始类。
加载
关于类加载,我们使用4W+1H的方式进行理解:
What:加载什么?
加载的是用二进制形式表示的类,也就是编译后的字节码文件中的内容。
When:何时加载?
一个类被加载的时机分为两种:
- 启动类:当前类被指定为初始类,那么JVM在启动时会首先对其进行加载。
- 引用:一个正要被加载的类直接或间接引用了当前类,比如:方法调用、字段访问、反射调用、继承、接口实现。
Who:谁来加载?
负责加载工作的通常是类加载器,所有的类加载器都继承自ClassLoader抽象类,它定义了类加载器的基本行为和步骤,子类可以进行自己的定制。
类加载器有如下分类:
- 引导类加载器:用于加载标准的二进制形式的字节码文件。在HotSpot虚拟中还有扩展类加载、应用类加载器,这是HotSpot虚拟机在实现JVM规范时的扩展。
- 自定义类加载器:可以根据需求自由发挥,加载来自网络、加密文件或者动态生成的字节码文件。
有一种特殊情况,当类型是数组时,将直接由虚拟机本身负责加载,数组中的组件类型依然由类加载器加载。
Where:加载到哪里去?
加载之后的类将会存放在方法区当中,当然这是JVM规范的规定,实际在实现JVM时会有所差异。比如:HotSpot虚拟机1.8版本(通常所说的JDK1.8)开始把方法区叫做MetaSpace。
How:如何加载?
类加载器可以自己完成对一个类的加载,也可以委托其它类加载器来加载。由此,出现了以下两个概念:
- 发起加载的加载器被称为被加载类的初始加载器。
- 实际完成加载的加载器被称为被加载类的定义加载器。
初始加载器和定义加载器并不一定是同一个。
这里涉及到另外一个问题:在运行时,如何区分一个类或接口?类或接口的区分并不仅仅通过名字,而是通过它的二进制名字和定义类加载器共同区分。
链接
链接是在加载之后执行的,是获取创建好的类或接口,将其与虚拟机运行时状态相结合的过程。
完整的链接过程包含以下三个步骤:
- 验证:验证字节码结构是否正确,是否符合约束条件。
- 准备:创建静态字段并设置默认值,默认值与类型相关,比如:int类型的默认值是0,Integer等引用类型的默认值是null。
- 解析:确认符号引用指向的真实地址。任何指令的执行都需要对符号引用进行解析,也包括本地方法的调用。
许多网文中提到:链接过程是解析符号引用,将其指向真实地址的过程。实际上这个解析是链接过程中的可选部分。JVM的实现者可以选择使用饿汉(eager)模式在这个阶段一次性全部解析,也可以使用懒汉(lazy)模式在使用时单独解析每个符号引用。
初始化
初始化过程就是执行类或接口的初始化方法(<clinit>)的过程。类在初始化之前,必须被链接,即:验证、准备且正常解析。
因为JVM是多线程的,类或接口的初始化需要谨慎的同步(采用等待-通知机制)。因为其它线程可能同时尝试初始化相同的类或接口,还可能递归地请求类或接口的初始化,递归会作为类或接口初始化的一部分。
在初始化的过程中,假设类对象已经被验证并准备好,类对象处于以下四种状态之一:
JVM的退出
JVM的退出有三种情况:
- System或Runtime类的exit方法,这是非强制的退出方式,所有子线程都执行完成后才会退出。
- Runtime类的halt方法,这是强制性的退出方式,立即退出。
- JNI(Java Native Interface)规范指出:当使用JNI 调用API加载或卸载JVM时会终止正在运行的JVM。
JNI是一个标准的编程接口,用于编写Java本地方法并将JVM嵌入到本地应用中。例如使用C/C++编写的程序调用JVM。
猜你喜欢
- 2024-10-02 Maven 的这 7 个问题你思考过没有?
- 2024-10-02 220、Class.forName 和 ClassLoader 有什么区别?
- 2024-10-02 原型模式(Prototype)(原型模式和工厂模式区别)
- 2024-10-02 Alluxio使用贴士:客户端显示找不到FileSystem类问题分析与解决
- 2024-10-02 异常还不知道是什么?一文教会你异常是什么,如何优雅处理
- 2024-10-02 十年架构师干货总结:Java 的类加载机制
- 2024-10-02 线上故障排查全套路盘点,运维大哥请自查
- 2024-10-02 一文读懂 Java 异常处理(java异常处理的方法)
- 2024-10-02 反射必杀技:深入了解Class类,让你一通百通
- 2024-10-02 Java异常的面试问题及答案-Part 2
- 最近发表
- 标签列表
-
- cmd/c (57)
- c++中::是什么意思 (57)
- sqlset (59)
- ps可以打开pdf格式吗 (58)
- phprequire_once (61)
- localstorage.removeitem (74)
- routermode (59)
- vector线程安全吗 (70)
- & (66)
- java (73)
- org.redisson (64)
- log.warn (60)
- cannotinstantiatethetype (62)
- js数组插入 (83)
- resttemplateokhttp (59)
- gormwherein (64)
- linux删除一个文件夹 (65)
- mac安装java (72)
- reader.onload (61)
- outofmemoryerror是什么意思 (64)
- flask文件上传 (63)
- eacces (67)
- 查看mysql是否启动 (70)
- java是值传递还是引用传递 (58)
- 无效的列索引 (74)