概述

JVM是Java Virtual Machine的缩写,即Java的虚拟机。它是一个虚构出来的计算机,是通过在实际的计算机上仿真模拟各种计算机功能来实现的。为了可以能好的理解更好的了解这个虚构出来的计算机,我们可以先看看真实的计算机。

    下图是微型计算机的基本结构:

    

单片机交互java 单片机jvm_存储

如上图所示,一个真正的计算机需要这样几个设备:I/O,运算器,存储器,控制器。

I/O:在控制器的控制下,完成输入和输出的任务;

运算器:在控制器的控制下,从存储器中得到数据和指令然后进行运算,最后将结果保存在存储器中;

控制器:控制整个计算器的行为;

 

    可以参考最简单的51单片机来看看其如何实现一个简单计算机:

单片机交互java 单片机jvm_jvm_02

    

原理很简单,但这里提到51单片机只是为了,我们可以更好的理解虚拟机需要虚拟什么功能。

                  

    简单的说JVM包涵如下功能模块:

1.  一套字节码指令集;

2.  JVM寄存器

3.  JVM栈结构

4.  JVM碎片回收堆

5.  JVM存储方法域

    下面将分别介绍这些功能模块。

字节码指令集

JVM指令系统同其他计算机的指令系统极其相似。即可以想象成Java的汇编语言。Java指令也是由 操作码和操作数两部分组成。操作码为8位二进制数,操作数紧随在操作码的后面,其长度根据需要而不同。当长度大于8位时,操作数被分为两个以上字节存放。操作码用于指定一条指令操作的性质。

Java指令系统是以Java语言的实现为目的设计的,其中包含了用于调用方法和监视多线程系统的指令。Java的8位操作码的长度使得JVM最多有256种指令,目前已使用了160多种操作码。

这和51单片机中的指令寄存器是同样的功能。

寄存器

所有的计算机的CPU均包含用于保存系统状态和处理器所需信息的寄存器组。JVM有4个最为常用的寄存器。

1.   pc程序计数器   

2.   optop操作数栈顶指针   

3.   frame当前执行环境指针   

4.   vars指向当前执行环境中第一个局部变量的指针   

所有寄存器均为32位。pc用于记录程序的执行。optop,frame和vars用于记录指向Java栈区的指针。

这和51单片机中的程序计数器和堆栈指针完成相似的功能,即保存和记录运行程序的一系列资源和环境。

 

栈结构

Java栈是JVM存储信息的主要方法。当JVM得到一个Java字节码应用程序后,便为该代码中一个类的每一个方法创建一个栈框架,以保存该方法的状态信息。

每个栈框架包括以下三类信息:

1.   局部变量   

2.   执行环境   

3.   操作数栈   

局部变量用于存储一个类的方法中所用到的局部变量。vars寄存器指向该变量表中的第一个局部变量。

执行环境用于保存解释器对Java字节码进行解释过程中所需的信息。它们是:上次调用的方法、局部变量指针和操作数栈的栈顶和栈底指针。执行环境是一个执行一个方法的控制中心。

当解释器要执行iadd(整数加法),首先要从frame寄存器中找到当前执行环境,而后便从执行环境中找到操作数栈,从栈顶弹出两个整数进行加法运算,最后将结果压入栈顶。

将寄存器的数据放入这个栈结构中,然后完成Java的运算功能,和51单片机中的运算器是一样的功能。

 

JVM碎片回收堆

      Java类的实例所需的存储空间是在堆上分配的。解释器具体承担为类实例分配空间的工作。解释器在为一个实例分配完存储空间后,便开始记录对该实例所占用的内存区域的使用。一旦对象使用完毕,便将其回收到堆中。在Java语言中,除了new语句外没有其他方法为一对象申请和释放内存。对内存进行释放和回收的工作是由Java运行系统承担的。

      对于这个JVM 的GC过程是比较复杂的过程,以后进一步说明。

 

JVM存储区

      JVM有两类存储区:

1.    常量缓冲池:存储类名称、方法和字段名称以及串常量;

2.    方法区:存储Java方法的字节码

所以Java应用程序的存储布局必须在运行过程中确定,依赖于具体平台的实现方式。JVM是为Java字节码定义的一种独立于具体平台的规格描述,是Java平台独立性的基础。

 

 

 

 

如下图是运行一次Java程序的一个简单流程:

单片机交互java 单片机jvm_虚拟机_03