我们知道java程序是把java源文件编译成字节码.class文件,然后交给JVM执行。那么java到底是解释执行还是编译执行的语言呢?
这个没有固定的答案,具体要要看用什么样的JVM。JVM把class文件编译成机器码执行那就是编译执行,如果JVM对class加载后由JVM解释执行就是解释执行。有的JVM即有yo解释执行也有编译执行。
JVM的种类:
hotspot jvm:这是最常用的JVM实现,由Oracle开发。HotSpot JVM提供了高效的执行引擎和垃圾回收机制,支持多种垃圾回收算法,如Parallel GC、CMS GC、G1 GC等。它广泛应用于服务器和桌面应用程序中
openJ9 jvm:由IBM开发,专注于高性能和低内存消耗。OpenJ9 JVM在性能和资源利用方面表现出色,适用于需要高性能和资源优化的应用场景
graalm: 由Oracle开发,是一个通用虚拟机,支持多种编程语言。GraalVM不仅支持Java,还支持其他语言如JavaScript、Python等,适用于需要多语言支持和高性能的应用
zing jvm: 由Azul Systems开发,专注于低延迟和高吞吐量。Zing JVM在金融交易等对延迟要求极高的场景中表现出色
dalvik jvm: 用于Android平台,是Android特有的JVM变体。Dalvik JVM优化了移动设备的资源利用,适用于Android应用程序的运行
我们后面重点讲hotspot jvm也是应用最广泛的
hotspot源码下载:
https://download.java.net/openjdk/jdk8
由于篇幅限制,关于源码编译这里不再熬述。
1 java虚拟机与程序的生命周期:
1.1 执行了System.exit()方法
1.2 程序正常执行结束
1.3 程序在执行过程中遇到了异常或错误异常中止(一般是主线程的异常中止)
1.4 由于操作系统的错误而导致java虚拟机进程的中止
2 类加载,链接,初始化
2.1 加载:查找并加载类的二进制数据
JVM规范规定类加载器在预料类将要被使用时预先加载它,有个预热的过程。类加载器在程序主动使用某一个类时才报告错误。加载完成以后进入到连接阶段
2.2 连接
将已经读入到内存的二进制数据合并到虚拟机的运行环境中,然后进行一系列的验证,确保被加载类的正确性。
2.3 准备阶段
在该阶段,java虚拟机为类的静态变量分配内存,并设置默认的初始值
2.4 解析
该阶段java虚拟机会把类的二进制数据中的符号引用替换为直接引用
2.5 初始化
为类的静态成员变量赋予正确的初始值
3 java程序对类的使用主要分为两种
3.1 主动使用
创建类的实例。例如:new Test()
访问某个类或接口的静态变量
调用类的静态方法
反射
初始化一个类的子类
虚拟机启动时被表明为启动的类
3.2 被动使用
除掉以上的情况属于被动使用,不会导致类的初始化。虚拟机实现必须在每个类或接口被java程序首次使用时才初始化。
类的加载指的是将类的.class文件中的二进制数据读入到内存中,将其方法存进运行时数据区的方法区内。然后在堆区创建一个Java.lang.Class对象,用来封装在类在方法区内的数据结构。