JVM介绍

来源:互联网 发布:网络碧池是什么意思 编辑:程序博客网 时间:2024/05/29 13:53

        JVM 是Java Virtual Machine(JVM )的缩写,JVM 是一种用于计算设备的规范,它是一个虚构出来的计算机,是通过在实际的计算机上仿真模拟各种计算机功能来实现的。

        一般的高级语言如果要在不同的平台上运行,至少需要编译成不同的目标代码。而引入Java 语言虚拟机后,Java 语言在不同平台上运行时不需要重新编译。Java 语言使用JVM 屏蔽了与具体平台相关的信息,使得Java 语言编译程序只需生成在JVM 上运行的目标代码(字节码),就可以在多种平台上不加修改地运行。JVM 在执行字节码时,把字节码解释成具体平台上的机器指令执行。这就是Java 的能够“一次编译,到处运行”的原因。

        JVM 与JDK、JRE的关系从下图可以很清晰的了解,图中蓝色部分为JVM ,从图中了解到JVM 从属于JRE 。



        类似的运行一个Java程序需要经历以下几个步骤:
        首先,要编写一个Java 程序,将其保存为.java 类型文件;
        然后,通过JDK bin目录下的javac 应用程序将.java 文件编译成.class 类型文件;
        最后,通过JDK bin目录下的java 应用程序执行.class 文件,输出结果。

 

        我们很容易就会判断出前两步应该不属于JVM 范畴,因为JVM 最大的特点就是“执行Java程序”,可以简单的理解为只有需要运行的Java 程序才会涉及到JVM 。程序开始执行时JVM 运行,程序结束后JVM也随之停止。你在同一台机器上运行三个程序,就会有三个运行中的JVM 进程。

JVM 总是开始于一个main() 方法,这个方法必须是公有、返回void、直接受一个字符串数组。在程序执行时,必须给JVM 指定main() 方法所在类。
        main() 方法是程序的起点,他被执行的线程初始化为程序的初始线程。程序中其他的线程都由他来启动。Java 中的线程分为两种:守护线程(daemon)和普通线程(non-daemon)。守护线程是JVM 自己使用的线程,比如负责垃圾收集的线程就是一个守护线程。当然,你也可以把自己的程序设置为守护线程,这里main() 方法的初始线程不是守护线程。

        只要JVM 中还有普通的线程在执行,JVM 就不会停止。如果有足够的权限,你可以调用exit()方法终止程序。

        从进程管理器中就可以清晰的看到,当我运行3个HelloWorld 程序后,进程管理器中出现了3个javaw 进程,并且全部为普通进程,如图所示:

 


        那么JVM到底是一种概念还是一种物理结构呢?弄清楚JVM 到底是什么对JVM 的学习至关重要!

首先从JVM 结构说起,JVM 结构如下图所示:

 


        JVM 由一个"class loader subsystem"(类加载器子系统:用于加载符合JVM 规格的类型(类或接口)、"execution engine"(执行引擎:负责执行已经加载类中的方法)和"runtime data areas"(运行时数据区:用于存储运行时数据) 这三部分组成。


        类装载器子系统(class loader subsystem),顾名思义,就是用来装载.class 文件的。JVM 的两种类装载器包括:启动类装载器和用户自定义类装载器,启动类装载器是JVM 实现的一部分,用户自定义类装载器则是Java 程序的一部分,必须是ClassLoader 类的子类。

 

        执行引擎(execution engine):执行字节码或本地方法。 

 

        运行时数据区(runtime data areas):包括一套字节码指令集、一组寄存器、一个栈、一个垃圾回收堆和一个存储方法域这5部分组成,如图所示:

 


        JVM 的组成结构已经清晰明了,可以说JVM 既是一种概念又是一种程序包组成,他由诸如java ,javaw ,jvm.dll 等文件组成。单独拿出来任何文件都无法说明他是JVM 即使把所有与JVM 有关的文件放在一起也无法证明这就是"JVM"。所以无法像上图界定JDK 与JRE 那样简单的界定JVM。


        JVM 有9种数据类型,其中前7种为基本数据类型,他们是:

 

TypeRangebyte8-bit signed two's complement integer (-27 to 27 - 1, inclusive)short16-bit signed two's complement integer (-215 to 215 - 1, inclusive)int32-bit signed two's complement integer (-231 to 231 - 1, inclusive)long64-bit signed two's complement integer (-263 to 263 - 1, inclusive)char16-bit unsigned Unicode character (0 to 216 - 1, inclusive)float32-bit IEEE 754 single-precision floatdouble64-bit IEEE 754 double-precision floatreturnAddressaddress of an opcode witdin tde same metdodreferencereference to an object on tde heap, or null

 

        他们的关系体系如下图所示:

 


        几乎所有的Java类型检查都是在编译时完成的。上面列出的原始数据类型的数据在Java执行时不需要用硬件标记。操作这些原始数据类型数据的字节码(指令)本身就已经指出了操作数的数据类型,例如iadd、ladd、fadd和dadd指令都是把两个数相加,其操作数类型别是int、long、float和double。虚拟机没有给boolean(布尔)类型设置单独的指令。boolean型的数据是由integer指令,包括integer返回来处理的。boolean型的数组则是用byte数组来处理的。虚拟机使用IEEE754格式的浮点数。不支持IEEE格式的较旧的计算机,在运行Java数值计算程序时,可能会非常慢。

        注:Java数组被当做object处理。


        以上就是对JVM 的一些介绍,相关JVM 的名词解释及概念会以专题文章形式展现。