Java虚拟机(JVM)概述

JVM(Java虚拟机)是一个抽象的计算模型。就如同一台真实的机器,它有本身的指令集和执行引擎,能够在运行时操控内存区域。目的是为构建在其上运行的应用程序提供一个运行环境。JVM能够解读指令代码并与底层进行交互:包括操做系统平台和执行指令并管理资源的硬件体系结构。本文主要对JVM进行概述,并介绍Java程序是如何在上面执行的。html

虚拟机

从本质上讲,虚拟机是个被构建来提供特定或通用目的服务环境的非实体计算机。这听起来像是一个仿真器,用来仿真机器未配置或不能按要求执行任务的硬件组件。所以,咱们要作的就是建立一个软件,以软件的形式模拟硬件提供的服务,使之看起来这个特定的硬件在系统中是实际存在的。虚拟机在必定程度上使用CPU虚拟化,为实际的硬件问题提供一个接口。因此能够说它实际上有两种功能:提供一个虚拟的环境,或者将某些不存在的事物进行抽象化。可是当咱们深刻了解以后会发现,这两种功能有着很明显的不一样。咱们如今暂且不看它们之间的不一样点,它们的共同点在于都“伪装”成它们不是的东西。正如Popek和Goldberg在论文“Formal Requirements for Virtualizable Third Generation Architectures”里说的,它是“一个真实机器有效、独立的复制品。”java

基于不一样的需求和用途,虚拟机有不少类型。一种叫彻底虚拟化(full virtualization),这种虚拟机表现得像一台真正的机器。其余类型的虚拟机会更精细,更专业,好比进程虚拟化(process virtualization)。而对JVM进行分类是很困难的,由于它对CPU进行了虚拟化,有本身的运行时环境、与底层平台协调工做的内存管理器、垃圾收集器,固然还有大量做为中间字节码输入的类库,最后但一样重要的是,它可以模拟机器的寄存器、堆栈等等。简单地说,它是被Java编译器编译为java的本质——字节码的游乐场。字节码其实是JVM用来将代码从新翻译为本地机器指令所使用的机器代码。编程

类文件格式

有趣的是,其实JVM并不关心Java语言或其余编程语言的语义和语法结构。当JVM执行一段程序的时候,它主要关注的是一种称为“类文件”的特定文件格式。*.class类文件格式和Java代码定义的面向对象的类结构毫无关系。编译器将*.java文件编译成*.class文件,而后JVM对*.class文件进行解译,它不关心这个类文件是由哪一种编译器生成的,只要符合类文件的文件格式便可。Java编译器将一段程序编译为等价的类文件。这些类文件实际上包含了半编译的代码——字节码。之因此称之为半编译,是由于字节码并不像C/C++编译器编译的二进制文件同样会被直接执行。字节码要先被输入到JVM中,而后再转换为底层平台能够执行的最终指令。因此字节码包含了JVM的指令、符号表和其余的辅助信息。无论何种语言,能根据JVM的语法和结构约束编译生成字节码的编译器,都是一个能够在JVM上执行的候选者。bootstrap

JVM的定位

JVM将自身定位于字节码和底层平台之间。底层平台是指操做系统(OS)和硬件。操做系统和硬件体系结构在不一样的机器上可能不一样,可是同一段Java程序能够不用作任何的代码修改就能在不一样的机器上运行。这是在虚拟环境中执行的程序语言的独特之处。例如,由其余程序语言编译器编译的目标代码如C++和Java相比的不一样点在于,C++程序须要被特定平台的编译器从新编译,从而使它能在不一样的体系结构上面运行。而Java代码并不须要作任何改变,由于由Java编译器编译的字节码是在外围的JVM上执行。所以,JVM负责从新解译由Java编译器生成的字节码,并和底层平台协调工做。也就是说,尽管Java编译器生成的结果是平台独立的,但JVM与特定平台相关的。除非两台机器有相同的体系结构,在某个体系结构上安装和使用的JVM可能换一台机器就不能正常工做了。数组

相对于JVM, JRE和JDK又是什么?

想要运行Java程序,咱们须要JVM由于它提供了字节码的运行环境。Oracle提供了两种不一样的产品:JDK(Java开发工具)和JRE(Java运行环境)。JRE是咱们安装运行Java程序的最基本软件。它和Java类库以及运行Java程序所须要的其余组件一块儿够成了JVM的一个实现。因此,若是咱们想运行一个类文件或一段字节码,仅须要JRE就够了。而JDK(Java开发工具)是JRE的超集。它包含了JRE提供的全部东西,包括建立类文件的工具如Java编译器、调试器和其余许多开发Java程序相关的工具。因此,当咱们要建立类文件(编译Java源码)时,咱们就须要JDK。下面是一张Java API文档的截图。注意组成JDK,JRE和Java SE API核心类库的组件;经过这张截图你能够了解JRE和JDK里面都有哪些内容。jvm

Java提供了Java虚拟机规范来让咱们对JVM的工做原理有一个完整的认识。你能够从这里获得概念性知识,并开发一个本身的JVM;但这并非一个简单的工做。如今市场上已经有不少JVM了,其中有些是免费的,还有一些须要购买商业许可证才能使用。编程语言

在JVM上执行Java程序

每个在JRE上运行的Java程序都会建立一个JVM实例。编译后的Java类文件和其余被依赖的类文件会被加载到运行环境中。这一步由类加载器协助完成。工具

类加载器经过三步完成类加载。性能

Firstly, it loads the program classes, along with standard Java classes that are bundled with JDK in the form of bytecode. The standard classes form the core API library of Java. The bootstrap begins by locating the core API libraries classes typically situated in jre/lib.开发工具

首先,类加载器会以字节码的形式加载程序类文件和与JDK绑定的标准Java类文件。标准类文件构成了Java API核心类库。引导程序经过定位一般位于jre/lib目录下的核心API类库启动。

而后,扩展机制定位扩展类库,例如一些为开发或执行代码而被添加到Java里新的(可选)包。扩展类一般位于 jre/lib/ext目录下。有时,扩展类会被放到系统属性java.ext.dirs 定义的其余目录下面。程序包使用JAR或ZIP的扩展名。

最后,若是要加载的类没有在Java的标准类库或扩展类库中被找到,加载器会搜索CLASSPATH环境变量下定义的文件路径,CLASSPATH里面包含了诸多存储类文件的地址。系统属性java.class.path对CLASSPATH环境变量作了映射。

像JAR或ZIP这样的归档文件都是包含了一些其余文件目录的独立文件,一般是压缩文件格式。例如,程序中使用的标准类库包含在归档文件 rt.jar中,该文件会和JDK被一同安装。

一旦文件被定位并加载以后,类加载器会执行不一样的功能,例如根据JVM的约束进行校验、内存分配,或者在调用构造器设置定义的变量元素以前使用默认值初始化类变量。

当加载程序结束以后,字节码指令被传递给执行引擎。而后JVM借助于绑定到指定平台的特定JVM实现的本地代码和底层操做系统进行交互。请注意,不一样平台的实现可能有略微不一样。

数据存储区的堆空间用于存储动态或临时分配的内存空间。类和数组是在这块区域里建立的。当建立对象大小超出堆内存空间时,垃圾收集器会回收内存。

Java栈,又叫栈帧,用于存储局部变量和不一样阶段方法调用的临时结果。每一次方法调用都会建立一个栈帧。

方法区基本上是JVM线程间的共享存储区。

寄存器是一个模拟的底层机器寄存器,主要用于执行字节码指令。PC寄存器或程序计数器是用于保存当前指令执行地址的主要寄存器。

JVM功能概述

JVM的功能能够概括为:

  • 加载:经过类加载器加载类文件的过程。
  • 连接:连接类文件,提交给JVM在运行时执行。
  • 初始化:分配内存和调用类初始化方法设置变量值。

总结

使用虚拟机执行程序的最大好处是它是平台独立的。和C/C++这种高效的语言相比,这种类型编程语言的生产力能够弥补其性能上的弱点。本文仅仅是对JVM的一点浅见,但也许已经足以帮助理解JVM是如何实际工做的。

原文连接: developer 翻译: ImportNew.com 辰午
译文连接: http://www.importnew.com/29224.html

相关文章
相关标签/搜索