我们在运行Java版的HelloWorld程序的时候, 敲入的命令并不是 ./HelloWorld.class 。 因为class文件并不是可以直接被操作系统识别的二进制可执行文件 。 我们敲入的是java这个命令。 这个命令说明, 我们首先启动的是一个叫做java的程序, 这个java程序在运行起来之后就是一个JVM进程实例。
上面的命令执行流程是这样的:
java命令首先启动虚拟机进程,虚拟机进程成功启动后,读取参数“HelloWorld”,把他作为初始类加载到内存,对这个类进行初始化和动态链接(关于类的初始化和动态链接会在后面的博客中介绍),然后从这个类的main方法开始执行。也就是说我们的.class文件不是直接被系统加载后直接在cpu上执行的,而是被一个叫做虚拟机的进程托管的。首先必须虚拟机进程启动就绪,然后由虚拟机中的类加载器加载必要的class文件,包括jdk中的基础类(如String和Object等),然后由虚拟机进程解释class字节码指令,把这些字节码指令翻译成本机cpu能够识别的指令,才能在cpu上运行。
从这个层面上来看,在执行一个所谓的java程序的时候,真真正正在执行的是一个叫做Java虚拟机的进程,而不是我们写的一个个的class文件。这个叫做虚拟机的进程处理一些底层的操作,比如内存的分配和释放等等。我们编写的class文件只是虚拟机进程执行时需要的“原料”。这些“原料”在运行时被加载到虚拟机中,被虚拟机解释执行,以控制虚拟机实现我们java代码中所定义的一些相对高层的操作,比如创建一个文件等,可以将class文件中的信息看做对虚拟机的控制信息,也就是一种虚拟指令。
JVM究竟是什么
JVM,Java Virtual Machine,中文就是Java虚拟机了, 和名字一样就是个虚拟机器,来模拟通用的计算机,有着一套虚拟的完善的硬件架构,如处理器、堆栈、寄存器等,还具有相应的指令系统。 JVM是一种规定好的标准规范, 定义了.class文件在其内部运行的相关标准和规范。一般来讲,所有的JVM都是基于栈结构的运行方式。那么不符合这种要求的,不算是JVM, 如Android中所使用的Dalvik 虚拟机就不能称作是JAVA 虚拟机, 因为它是基于寄存器(最新的Android系统据说已经放弃了Dalvik VM, 而是使用ART)。
JVM相关实现的产品有很多, 通常最有名最常用的就是现在Oracle公司所有的HotSpot 虚拟机。Java语言与 JVM之间的关系
Java程式可以跨平台,这是你在许多书或文件早就看过的描述,但是跨平台是怎麽一回事?在这之前,你得先了解跨平台是怎麽一回事。
其实对于电脑而言,它只认识一种语言,也就是0101序列所组合而成的指令。当你使用的是C/C++等之类的高阶语言编写代码时,其实这些语言,都是比较贴近人类语言的语法,不过大部门都是英语语义,对我们来说还是不够亲切,这都是很多小白入门学习的障碍了。这是为了方便人类阅读及编写,计算机也看不懂C/C++这类语言。
你要有个「翻译员」将你写的C/C++代码,翻译为电脑看得懂的0101序列指令,这个翻译员就是所谓的「编译器」(Compiler):
问题在于,每个平台所认识的0101序列并不一样。在Windows上也许某个指令是0101,在Linux下也许是1010,因此不同的平台必须使用不同的编译器来编译你的代码,而在Windows平台上编译好的程序,也不能直接拿到Linux等其它平台上执行,而必须经过重新编译的动作,让编译器将你的程式编译为该平台可以执行的指令。
由于每个平台的特性不同,可引用的函数程序库(Library)不同,也许你的代码还得作修改,才可以在另一个平台上编译执行。这很不方便,就是说如果你在Windows设计了一款游戏,想要卖给Linux的使用者,就得再花费一些功夫。这也是为什么大部分游戏或者软件只能在Windows运行了。
Java 也是个高阶语言,要让电脑执行你编写的应用程序,也是得借助编译器的翻译。不过,Java编译时,并不直接翻译为相依于某平台的0101指令,而是翻译为中介格式的位元码(byte code)。Java 的原始码文件格式名为.java,经过编译器翻译过后,会变成.class的格式文件位元码。如果想要执行这个位元码档案,目标平台上必须安装有JVM(Java Virtual Machine)。JVM会将位元码翻译为相应平台支持的语言。
不同的平台必须安装该平台相对应的JVM。这就好比你讲中文(.java),Java编译器帮你翻译为英文(.class)。之后该英文文件,到当地之后,再由当地看得懂英文的人翻译为当地的方言。
所以JVM所担任的职责之一,就是当地的翻译员,将位元码文件翻译为当时作业系统看得懂的0101序列。不过这不是最重要的,基本上如果只是要翻译员的话,直译器(Interpreter )就办得到了。
JVM有个很重要的观念就是:「对于Java程式而言,其实它只认识一种作业系统(或说是一种机器),这个系统叫作JVM,而对于JVM而言,位元码文件就是它的可执行文件!也就是格式为.class的文件。Java代码程序,理想上,并不用理会真正执行于哪个平台之上,它只要知道如何执行于JVM之上就可以了,至于JVM实际上如何与底层平台作沟通,则是JVM自己的事!」这个观念非常的重要,对于以后能够搞清楚所PATH变量与CLASSPATH变量的概念,也有一定的帮助。
摘自:CSDN -- Java究竟为什么需要 JVM(Java虚拟机)?
重点:
Java 的原始码文件格式名为 xx.java,经过编译器翻译过后,会变成*.class的格式文件位元码。
JVM会将位元码翻译为相应平台支持的语言
不同的平台必须安装该平台相对应的JVM