写在开头:此系列文章是观看尚硅谷宋红康老师讲解JVM的随笔记录,以及自己的一些个人理解。
目录
1. 虚拟机与Java虚拟机介绍
- 虚拟机:所谓虚拟机,就是一台虚拟的计算机,是一款软件,用来执行一系列虚拟计算机指令。大体上,虚拟计算机可分为系统虚拟机和程序虚拟机。
- 系统虚拟机:visual box和VMware。完全是对物理计算机的仿真,提供了一个可运行完整操作系统的平台。
- 程序虚拟机:Java虚拟机。专门为执行单个计算机程序和设立。Java虚拟机中执行的指令我们成为Java字节码指令。
1.1 Java虚拟机
java虚拟机是一台执行java字节码的虚拟计算机,有独立的运行机制。其中运行的java字节码,未必有java语言编译而成。
JVM平台的各种语言可以共享Java虚拟机带来的跨平台性、优秀的垃圾回收器,和可靠的即时编译器。
特点:
- 一次编译,到处执行
- 自动内存管理(内存管理降低了内存泄漏和内存溢出的风险)
- 自动垃圾回收功能
2. JVM位置和整体结构
JVM运行在操作系统之上,它与硬件没有直接的交互。
方法区和堆表示多线程共有,其他代表各自线程单独会使用各自的。
其中执行引擎又分为解释器、JIT编译器(即时编译器Just-In-Time Compiler)、垃圾回收器
及时编译器的作用(编译器的后端,前端指将高级语言编译为字节码):对于一些高频使用、反复执行的热点代码,将其字节码编译成机器指令并缓存起来,以供操作系统直接使用,增加运行速度。
3. Java代码的执行流程
更加详细的流程图
PS:当设计一门编程语言时,若使用JVM,则只需要生成的字节码文件满足java虚拟机的规范就可以了。重点就是设计语言的语言和前端编译器。
主流vm采用解释执行和及时编译并存方式
解释器:保证响应时间,对字节码逐行执行
JIT:字节码指令→机器指令(同时缓存起来),二次编译,保证执行性能
4. JVM架构模型
Hotspot只有PC寄存器,任何操作都需要入栈和出栈操作。
零地址指令:基于栈的指令大部分都是零地址指令。执行一个指令时,通常需要地址和操作数。一、二地址指令需要一、二个地址。而栈只针对栈顶元素进行操作,其他数据不操作,所以不需要地址了
JVM可以跨平台,不需要硬件支持,所以可移植性更好。
JVM指令集小,但是用的指令较多
4.1 编程实例(安装后自己再编码实现)
执行完成后,对字节码文件进行反编译
此时直接出现5,并保存然后结束
修改代码后重新编译,指令出现了8行:
这里如果使用寄存器架构的指令行数就很少了。
4.2 架构模型总结
由于跨平台性的设计,Java的指令都是根据栈来设计的。不同平台CPU架构不同,所以不能设计为基于寄存器的。
优点是跨平台,指令集小,编译器容易实现;缺点是性能下降,实现同样的功能需要更多的指令。
5. JVM的生命周期
5.1 虚拟机的启动
- Java虚拟机的启动是通过引导类加载器(bootstrap class loader)创建一个初始类(initial class)来完成的,这个类是有虚拟机的具体实现指定的。因为虚拟机运行的平台各不相同。
5.2 虚拟机的执行
- 一个运行中的Java虚拟机有着一个清晰的任务:执行Java程序
- 程序开始执行时它才运行,程序结束时它就停止。
- 执行一个所谓的Java程序的时候,真真正正在执行一个叫做Java虚拟机的进程。
5.3 虚拟机的推出
- 程序正常执行结束
- 程序在执行过程中遇到了异常或错误而异常终止
- 由于操作系统出现错误而导致Java虚拟机进程终止
- 某县城调用Runtime类或System类的exit方法,或Runtime类的halt方法,并且Java安全管理器也允许这次exit或halt操作。
- 除此之外,JNI规范描述了用JNI INVOCATION API来加载或卸载Java虚拟机时,Java虚拟机的推出情况。
5.4实例
加段延时后,运行刚才编写的程序,这里jps代表当前执行的进程,这里我们看到有StackStruTest正在执行
程序结束后在jps 发现已经没有StackStruTest了,进程已经没有了
6.JVM发展历程
6.1 Sun Classic VM
不能都用JIT编译缓存的原因:Jit编译也是需要时间的,需要trade-off。
例如从A到B
解释器相当于一直在走路,JIT解释器相当于坐公交,但是坐公交之前都需要等一段时间。