首 页 行业热点 新车 试驾评测 养车用车 车型库

汇编器需要做哪些工作?

发布网友

我来回答

1个回答

热心网友

,其实java虚拟机就是bin目录下那个java.exe文件(我们执行一个java程序时要使用java命令就是执行这个程序,然后由它解释执行java程序)。

java虚拟机定义了很多指令,就像一个真正的机器的硬件一样,字节码通过这些指令操作java虚拟机,然后java虚拟机再将这些指令翻译为硬件指令。基本原理就是这样。

我想你迷惑的是java虚拟机是怎样执行一个java文件的对吧?
假设我们编写了一个java程序,编译后生成的字节码文件是Test.class,那么我们通常是这么运行我们的java程序的:
java Test
上面的命令的本意是“启动java.exe程序(即java虚拟机),并将"Test"这个字符串参数传递给它”(这一点了解DOS命令执行原理的人很容易理解)。
然后,操作系统会启动java.exe,它首先取得参数"Test",然后再传递给ClassLoader类(这个类在java.lang包中,当需要载入类时就会用到它),ClassLoader类查找classpath环境变量中指定的目录,如果没有定义classpath则默认为当前目录,在其中寻找"Test.class",.class后缀是自动加上去的,因此我们执行java程序时不能写成java Test.class,这样是找不到的(即使有Test.class.class文件也不行,因为此时的.号有另外的含义,它是包分隔符,因此这种情况下ClassLoader实际上找的是Test目录下的class.class文件)。

找到后,就将它载入java虚拟机,其实就是读取其中的二进制字节码,java虚拟机对它载入的类的字节码有很严格的要求,它首先检查这个文件中的字节码是否符合标准格式(这个检查是java虚拟机自己完成的,事实上,对字节码进行检查的规则有严格的定义,详见《java虚拟机规范》),检查没有问题后(如果我们用的是sun自己的编译器,并且我们没有改动过字节码文件,那么这个检查肯定是没有问题的,依照《java虚拟机规范》的解释,检查的目的是为了保持字节码的完整性,其实就是说担心其它人会改动字节码或其它编译器生成的字节码不符合规范)。

我们可以把编译后的字节码看成一条条指令和数据定义(就像汇编语言一样)。当前一步的检查通过后,java虚拟机开始真正载入这个类(检查阶段只是把这个类当成一个二进制格式的文本文件,并不是把它当作一个虚拟机可执行的程序)。在这个阶段,java虚拟机负责为类的数据分配内存,例如将数据装入常数池,将类的方法定义装入内存堆(池和堆是java虚拟机管理内存的逻辑单元,所有数据都在池中,所有可执行代码都在堆中,在需要时再将其取出并压入堆栈——不明白的话这一点可以略过)。

然后就是从这个类的入口函数(即main方法)开始执行:读取一条指令 > 翻译指令 > 执行指令 > 再读取下一条指令 > ......如此循环

(一般情况下是这样,但如果在执行过程中JIT,即java运行时系统将其中经常用到的一些指令编译为机器语言的话,再执行这些指令时就不需要翻译了——再罗嗦几句:尽管现在的java程序执行速度还不尽人意,但理论上,JIT系统可能会获得比C还要高的效率,因为编译后C的代码是死的,而JIT是在运行时编译,在这种情况下,容易知道哪些代码经常被使用,进而知道如何最大可能地优化这些代码,类似C语言的编译器在静态情况下是无法做到的)。

声明声明:本网页内容为用户发布,旨在传播知识,不代表本网认同其观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。E-MAIL:11247931@qq.com