深入理解Java虚拟机_动力节点Java学院整理

  

  

Java程序必须在虚拟机上运行。那么虚拟机到底是什么呢?先看网上搜索到的比较靠谱的解释:

  

虚拟机是一种抽象化的计算机,通过在实际的计算机上仿真模拟各种计算机功能来实现的. Java虚拟机有自己完善的硬体架构,如处理器,堆栈,寄存器等,还具有相应的指令系统.JVM屏蔽了与具体操作系统平台相关的信息,使得Java程序只需生成在Java虚拟机上运行的目标代码(字节码),就可以在多种平台上不加修改地运行。

  

这种解释应该算是正确的,但是只描述了虚拟机的外部行为和功能,并没有针对内部原理做出说明。一般情况下我们不需要知道虚拟机的运行原理,只要专注写java代码就可以了,这也正是虚拟机之所以存在的原因,屏蔽底层操作系统平台的不同并且减少基于原生语言开发的复杂性,使java这门语言能够跨各种平台(只要虚拟机厂商在特定平台上实现了虚拟机),并且简单易用。这些都是虚拟机的外部特性,但是从这些信息来解释虚拟机,未免太笼统了,无法让我们知道内部原理。

  

  

让我们尝试从操作系统的层面来理解虚拟机。我们知道,虚拟机是运行在操作系统之中的,那么什么东西才能在操作系统中运行呢?当然是进程,因为进程是操作系统中的执行单位。可以这样理解,当它在运行的时候,它就是一个操作系统中的进程实例,当它没有在运行时(作为可执行文件存放于文件系统中),可以把它叫做程序。

  

对命令行比较熟悉的同学,都知道其实一个命令对应一个可执行的二进制文件,当敲下这个命令并且回车后,就会创建一个进程,加载对应的可执行文件到进程的地址空间中,并且执行其中的指令。下面对比C语言和Java语言的HelloWorld程序来说明问题。

  

首先编写C语言版的HelloWorld程序。

        # include & lt; stdio.h>   # include & lt; stdlib.h>   int主要(空白){   printf (" hello world \ n”);   返回0;   }      C

编译语言版的HelloWorld程序:

  

1. gcc  HelloWorld.c  -o  HelloWorld ,

  

运行C语言版的HelloWorld程序:

  

1. zhangjg@linux:/产品开发/工作区/HelloWorld/src,美元。/HelloWorld ,,

  

2. hello  world ,

  

gcc编译器编译后的文件直接就是可被操作系统识别的二进制可执行文件,当我们在命令行中敲下。/HelloWorld这条命令的时候,直接创建一个进程,并且将可执行文件加载到进程的地址空间中,执行文件中的指令。

  

作为对比,我们看一下Java版HelloWord程序的编译和执行形式。

  

首先编写源文件HelloWord。java:

        公开课HelloWorld {   公共静态void main (String [] args) {   System.out.println (“HelloWorld”);   }   }      

编译Java版的HelloWorld程序:

  

1. zhangjg@linux:/产品开发/工作区/HelloJava/src,美元javac  HelloWorld.java ,,
  2. zhangjg@linux:美元/产品开发/空间/HelloJava/src, ls ,
  3. helloworld.class , HelloWorld.java ,

  

运行Java版的HelloWorld程序:

  

1. zhangjg@linux:/产品开发/工作区/HelloJava/src,美元java  -classpath 只HelloWorld ,,
  

  

2. helloworld ,

  

从上面的过程可以看的到,我们在运行Java版的HelloWorld程序的时候,敲入的命令并不是。/HelloWorld。类。因为类文件并不是可以直接被操作系统识别的二进制可执行文件。我们敲入的是java这个命令。这个命令说明,我们首先启动的是一个叫做java的程序,这个java程序在运行起来之后就是一个JVM进程实例只

  

  

java命令首先启动虚拟机进程,虚拟机进程成功启动后,读取参数“HelloWorld”,把他作为初始类加载到内存,对这个类进行初始化和动态链接(关于类的初始化和动态链接会在后面的博客中介绍),然后从这个类的主方法开始执行。也就是说我们的. class文件不是直接被系统加载后直接在cpu上执行的,而是被一个叫做虚拟机的进程托管的。首先必须虚拟机进程启动就绪,然后由虚拟机中的类加载器加载必要的类文件,包括jdk中的基础类(如字符串和对象等),然后由虚拟机进程解释字类节码指令,把这些字节码指令翻译成本机cpu能够识别的指令,才能在cpu上运行。

  

从这个层面上来看,在执行一个所谓的java程序的时候,真真正正在执行的是一个叫做java虚拟机的进程,而不是我们写的一个个类的文件。这个叫做虚拟机的进程处理一些底层的操作,比如内存的分配和释放等等。我们编写的类文件只是虚拟机进程执行时需要的“原料”。这些“原料”在运行时被加载到虚拟机中,被虚拟机解释执行,以控制虚拟机实现我们java代码中所定义的一些相对高层的操作,比如创建一个文件等,可以将类文件中的信息看做对虚拟机的控制信息,也就是一种虚拟指令。

深入理解Java虚拟机_动力节点Java学院整理