JVM简介
虚拟机(Virtual Machine)
虚拟机就是一台虚拟的计算机,是一款软件,用来执行一系列虚拟计算机指令。大体上,虚拟机可以分为系统虚拟机和程序虚拟机。
- 系统虚拟机,如VMware,完全是对物理计算机的仿真,提供了一个可运行完整操作系统的软件平台
- 程序虚拟机,如JVM,它专门为执行单个计算程序而设计,在JVM中执行的指令称为Java字节码指令
Java虚拟机(JVM)
Oracle拥有市场占用率最高的两款虚拟机:HotSpot和JRockit,并计划未来对它们进行整合:HotRockit。目前默认用的还是HotSpot,可以通过
java -version
命令的输出信息查看
Java虚拟机是一台执行Java字节码的虚拟计算机,它拥有独立的运行机制,其运行的Java字节码也未必有Java语言编译而成,也就是说,其他语言如JavaScript、Jython、Scala等经过它们自己的编译器编译为字节码文件后,这些字节码文件只要遵循Java虚拟机规范,Java虚拟机就能执行这些程序。
JVM平台的各种语言可以共享JVM带来的跨平台性、优秀的垃圾回收器,以及可靠的即使编译器。
Java虚拟机就是二进制字节码的运行环境,负责装载字节码到其内部解释/编译为对应平台上的机器指令执行。每一条Java指令,Java虚拟机规范中都有详细定义,如怎么取操作数,怎么处理操作数,处理结果放在那里。
几款JVM简介
(1)1996年Java 10版本的时候,Sun公司发布名为Sun Classic VM的Java虚拟机,是世界上第一款商用JVM,在JDK1.4时被淘汰
- 只提供解释器,如果使用JIT编译器,就要进行外挂,但是解释器和JIT编译器不能同时使用
- 现在的HotSpot内置了此虚拟机
(2)Exact VM
- jdk1.2提供了此虚拟机,解释器和JIT编译器可以混合工作
(3)HotSpot
- jdk1.3的默认虚拟机就是HotSpot,一直使用至今
(4)JRockit
- 专注于服务端应用,不太关注程序启动速度,因此JRockit内部不包含解释器实现,全部代码都靠编译编译后执行
(5)…还有很多JVM
JVM整体结构
JAVA执行流程图解
JIT(Just In Time)即时编译,将访问频率高的代码(称为热点代码)编译成机器指令存放到方法区中,下次再执行到热点代码的时候,就不需要逐行解释字节码成机器指令,而是直接使用编译好的机器指令,提高执行效率。
解释器由于能立即解释执行程序,因此得到更快的程序响应时间,而JIT编译器由于需要搜索热点代码,编译等过程导致响应时间没有解释器块,但是一旦程序编译好,则执行性能大大提高。因此编译器和解释器的协同工作,在最优化的程序响应时间与最佳执行性能中取得平衡。
JVM的生命周期
虚拟机的启动
Java虚拟机的启动是通过引导类加载器(bootstrap class loader)创建一个初始类(initial class)来完成的,这个类是由虚拟机的具体实现指定的。
虚拟机的执行
- 程序开始执行时虚拟机开始运行,程序结束时虚拟机停止
- 执行一个Java程序的时候,真正执行的是一个叫做Java虚拟机的进程
虚拟机的退出
有如下几种情况会导致虚拟机退出:
- 程序正常执行结束
- 程序在执行过程中遇到了异常或错误而异常终止
- 由于操作系统出现错误
- 某线程调用Runtime类或System类的eixt方法,或Runtime类的halt方法,并且Java安全管理器也允许这次exit或halt操作
JVM线程系统
使用jconsole或者其他调试工具会看到有许多线程在运行,这些后台线程不包括调用main方法的main线程以及所有这个main线程自己创建的线程。
这些后台系统线程在HotSpot JVM里主要是:
- 虚拟机线程
这种线程的执行类型包括“stop-the-world”的垃圾收集,线程栈收集,线程挂起以及偏向锁撤销 - 周期任务线程
这种线程是时间周期事件的体现(比如中断),他们一般用于周期性操作的调度执行 - GC线程
这种线程对在JVM里不同种类的垃圾收集行为提供了支持 - 编译线程
这种线程在运行时会将字节码编译到本地代码 - 信号调度线程
这种线程接受信号并发送给JVM,在它内部通过调用适当的方法进行处理