针对虚拟机的底层实现原理及相关实现过程,讨论了 Java 语言的跨平台原理以及相关工作机制,分析了 JVM 底层各数据区内存管理过程,阐述了 JVM 在 Java 语言中的核心作用以及重要地位。
目录
1 概述
2 Java 平台分层原理
3 虚拟机工作原理
4 虚拟机内存管理
5 类加载机制
6 结束语
1 概述
Java 语言的闪耀点是其跨平台特性,使其征服了网络编程界,而 Java 虚拟机以其独特的作用及强大的功能支撑 起Java平台的强大地位,Java虚拟机是连接应用程序与系 统平台及机器硬件的桥梁,是Java语言的核心基石。
2 Java 平台分层原理
1995 年 SUM 公司正式对外发布了第一个版本的 JDK 后,在编程界引起了极大的反响,随后几年风靡编程领域,从此之后各类面向对象跨平台编程犹如雨后春笋般的出现。把源文件转换成字节码文件,是Java语言的重要特征及显耀的光芒,为何其具有如此强 大的能力,归根到底就是因为虚拟机的重要作用。Java虚 拟机在计算机编程领域又称之为JVM,是一种用代码语句来模拟计算机元件功能的实现包。 大家都清楚,Java语言即不是一种完全解释型的语言,也不是一种完全编译型的语言,其源码文件会在编译命令的执行过程中转成字节码文件,由于字节码文件不是可执行文件,因而其不能直接被操作系统调用执行。字节码是一种字节流文件,其以 class 类型的文件存在,是一种跟平台不相耦合的类型文件,需要经过 JVM 的翻译转换才能被硬件环境识别。Java 平台体系结构可分为四层:最上面的为 Java 应用程序层;在此层的下面是 API 接口层,此层包含了众多的JDK核心类库;再往下一层就是JVM位置所在,JVM在此层完成字节码解释转换工作,JVM 层与 API 层共同构成 Java 语言的运行时环境(JRE);最下面一 层为机器硬件平台层,此层直接执行由 JVM 解释出来的二进制命令。
3 虚拟机工作原理
Java 虚拟机是操作系统中的一个 job,所有 Java 应用 程序均归属某一个虚拟机实例,当运行作为 Java 程序起点 的 Main 方法时,JVM便被创建。JVM便被创建后,在虚拟机job运行过程中会创建守护线程,守护线程的作用是监测非守护线程的执行过程,保障程序的完整执行,直到应用程序的退出。Java 虚拟机是连接应用与操作平台的桥梁,从字节码文件变成可执行的机器命令,JVM 的工作过程包含七个步骤,分别是:字节码装载、字节流校验、静态变量初始化、引用转换、对象实例化、反射调用、GC 回收,如表 1 所示。
第一步,装载 class 类型文件到内存中。本阶段的目标是要对数据进行初始化处理,衔接后继步骤,完成整个JVM工作过程的第一步。在这一阶段所要实现的具体内容是要通过类名来定位并导入相关的字节流,并生成一个与此类相关联的类型对象,作为该类的操作入口。
第二步,进行类的链接操作。在这一阶段主要负责将 二进制字节流的数据装入JRE环境,此阶段包含三个过 程:字节流校验、静态变量分配内存空间、引用转换。 验证过程完成对源码类的检查,以维护JVM自身的安全;准备过程完成源码类型结构的初始化;解析过程直接 对常量值初始化。
第三步,进行Java类的对象实例化过程。此步是加载 过程最后一步,在此阶段所要完成的任务是:执行超类、子类中各种静态语句块,按顺序执行父类、子类的构造器函数完成实例化过程。
第四步,运行Java类的相关功能。在此阶段类的功能 可以被机器以指令的方式执行。
第五步,卸载运行完毕的类对象。经过垃圾回收机制(GC)处理的最终会被JVM从内存中卸载。
4 虚拟机内存管理
虚拟机运行时会将正在使用的内存空间划分为不同的区域,每个区域负责不同的功能,各个区域的创建,销毁过程也都不相同。总的来说,JVM内存空间划分为两大块, 数据共享区与私有区,每大块又可以进一步细分,如表 2。
全局变量区:用于存储源码类中的全局变量,为各个线程的内存数据共享区域。
实例区:存放用new关键字定义并经过初始化的实例,此区空间会被GC释放,同为数据共享区。
局部变量区:用于存储源码类中的局部变量,数据为特定线程专用。局部变量周期与实例线程相同,为数据私有区,不可共享。
本地方法区:与局部变量区类似,只为本地局部 Native 方法使用,部分 JVM 中也会将其与虚拟机栈合并为一,同为数据私有区,不可共享。
字节码指令区:存储实例线程下一步所要执行的计算机指令,同为数据私有区,不可共享。
5 类加载机制
在JRE环境中,有多个层级的类加载器,如表3所示。最顶层的为:JDK根类加载器(Bootstrap),此类为所有类加在载器的总父类,次级类加载器(Extension)为其子类,直接继承了此父加载器,次级加载器类下面同样也存在一个继承子类,三级类加载器(Application),在此子类中开放了自定义接口,自用户可根据实际需要编码以实现自定义加载器的开发。
同时在 JRE 环境中,加载器的装载过程采用的是向上 传递装载的实现方式,当加载器收到请求要进行类装载 时,其会把相关请求发送给其直接父类,父加载器同样会 把请求向上递归传递,直到最顶层加载器。当最顶层的加 载器无法完成装载任务时,才会把请求交由子类完成,这就保证了在任务场景下类的加载任务均由最高的类加载 器完成,保证了所有类型的实例对象具有相同的一致性, 以避免应用程序的混乱。
6 结束语
虚拟机并不是真正的机器,是一种通过代码来实现硬 件功能的插件包。虚拟机有自己的模拟硬件环境,如全局及局部变量区、本地方法区、字节码区、实例区等,还有自己的指令系统。对Java 语言跨平台特性而言,虚拟机是其 核心构件,其直接关系应用程序的完整、健康执行,是 Java 语言的中枢组件。