1、JVM 简析:
作为一名Java 使用者,掌握 JVM 的体系结构是很有必要的。
说起Java ,我们首先想到的是Java 编程语言,然而事实上,Java 是一种技术,它由四方面组成:Java 编程语言、Java 类文件格式、Java 虚拟机 和 Java 应用程序接口(Java API)。他们的关系图如下:
Java平台
Java 平台由 Java 虚拟机和 Java 应用程序接口搭建,Java 语言则是进入这个平台的通道,用Java 语言编写并编译程序可以运行在这个平台上。这个平台的结构如下所示:运行期环境代表着Java平台,开发人员编写Java 代码(.java文件),然后将之编译成字节码(.class文件),再然后字节码被装入内存,一旦字节码进入虚拟机,它就会被解释器解释执行,或者被即时代码发生器有选择的转换成机器码执行。
Java平台无关性
JVM 在它的生命周期中有一个明确的任务,那就是运行Java 程序,因此当Java 程序启动的时候,就产生JVM 的一个实例;当程序运行结束的时候,该实例也跟着消失了。在Java 平台的结构中,可以看出,JVM 在核心的位置,是程序与底层操作系统和硬件无关的关键。它的下方是移植接口,移植接口由两部分组成:适配器和Java 操作系统,其中依赖平台的部分称之为适配器;JVM 通过移植接口在具体的平台和操作系统上实现;JVM 的上方是Java 基本类库和扩展类库以及他们的API,利用Java API 编写的应用程序(application)和小程序(Java applet)可以再任何Java 平台上运行而无需考虑底层平台,就是因为有Java 虚拟机(JVM)实现了程序与操作系统的分离,从而实现了Java 的平台无关性。
下面,我们从JVM 的基本概念和运行过程这两个方面入手,来对它进行深入的研究。
2、JVM 基本概念
(1)基本概念:
JVM 是可运行Java 程序的假想计算机,包括一套字节码指令集、一组寄存器、一个栈、一个垃圾回收、堆和一个存储方法域。JVM 是运行在操作系统之上的,它与硬件没有直接的交互。
(2)运行过程:
我们都知道Java 源文件,通过编译器,能够产生相应的.class文件,也就是字节码文件,而字节码文件又通过Java 虚拟机的解释器,解释成特定机器上的机器码。也就是如下:
① Java 源文件 ——> 编译器 ——> 字节码文件
② 字节码文件 ——> JVM ——> 机器码
每一种平台的解释器是不同的,但是实现的虚拟机是相同的,这也就是Java 为什么能跨平台的原因了,当一个程序开始运行,这时虚拟机就开始实例化了,多个程序启动就会存在多个虚拟机实例。程序退出或者关闭,则虚拟机实例消亡,多个虚拟机实例之间数据不能共享。
3、JVM 的体系结构
JVM 的体系结构
(1)Class Loader 类加载器
负责加载.class文件,class文件在文件开头有特定的文件标识,并且ClassLoader 负责class文件的加载。
类的生命周期:加载 ——> 验证 ——> 准备 ——> 解析 ——> 初始化 ——> 使用 ——> 卸载
1、加载:
① 通过一个类的全限定名,来获取此类的二进制字节码;
② 将这个字节码所代表的静态存储结构转化为方法区的运行时数据结构;
③ 在Java堆中生成一个代表这个类的Class对象,作为方法区这些数据的访问路口。
2、验证:文件格式验证、元数据验证、字节码验证等。
3、准备:准备阶段是正式为静态变量分配内存并设置静态变量初始值(各数据类型的零值)的阶段,这些内存将在方法区中进行分配。但是如果静态变量的字段属性为常量,则会初始化为指定的值,而不是零值。
4、解析:解析阶段是在虚拟机将符号引用替换为直接引用的过程。直接引用可以是直接指向目标的指针、相对偏移量。
5、初始化:为类的静态变量赋予指定的初始值。
6、使用:使用类之前,必须对类进行实例化,如new或者反射。只有实例化了,才能通过对象的引用来访问对象的实例。
7、卸载:执行垃圾回收。
在类的加载过程中,静态成员会优先加载;而普通成员则是使用的时候才会去加载。
加载顺序:
1. 虚拟机在首次加载 Java 类时,会对静态代码块、静态成员变量、静态方法进行一次初始化(静态间按顺序执行)。
2. 只有在调用 new 方法时才会创建类的实例。
3. 类实例创建过程:父子继承关系,先父类再子类。父类的静态->子类的静态->父类的初始化块->父类的构造方法->子类的初始化块->子类的构造方法
4. 类实例销毁时候:首先销毁子类部分,再销毁父类部分。
双亲委派机制:
JVM的类加载是通过ClassLoader及其子