你对JVM实现机制是否熟悉,这里和大家分享一下,Window的JVM能把字节码转换成Window系统的指令集,Linux的JVM能把字节码转换成Linux系统的字节,同理还有Solaris,它们彼此之间是不能通用的。
1.JVM实现机制
Java虚拟机就是一个小的计算机,有自己的指令集,有自己的文件系统,管理内部的表和数据,负责读取class文件里面字节码,然后转换成不同操作系统的CPU指令,从而使得Java程序在不同的操作系统上顺利的跑起来。所以Window的JVM能把字节码转换成Window系统的指令集,Linux的JVM能把字节码转换成Linux系统的字节,同理还有Solaris,它们彼此之间是不能通用的。
最早一款的原型虽然是Sun公司开发的,但发展到现在其实任何厂商都可以自己去实现一个虚拟机,用来读取字节码转换成OS指令。甚至我们可以认为JVM跟Java编程语言都没有关系,因为你自己哪怕用记事本写一串字节码,也可以让JVM来解析运行,只要你的字节码能通过JVM的验证。
JVM的验证其实是很严格的,这里只讲一些有趣的地方。大家还记得Java的图标是一个杯咖啡麽?究其历史我们也许可以查出为什么,但还有更显而易见的方式是JVM怎么判断一个文件是否是class文件?JVM的做法是读取前4个字节转换成16进制数,判断是否等于0xCAFEBABE这个数。注意到这个单词了麽?
“cafebabe”,代表着国外一种咖啡品牌,似乎叫做Peet’scoffee-baristas之类。创造Java的人为了方便记忆,选择了这样一个16进制数作为标准class文件的头,所以任何class文件都必须具有这4个字节的头部。我们可以用DataInput这个接口的实现类来验证一下,读取任何一个class文件的***个int,int在Java里面是四个字节。转换成16进制一定会是0xcafebabe的。
所以这里想告诉大家的是,JVM其实并没有那么神秘,我们完全可以理解它的构造。介绍完了JVM实现机制再来看一下JVM内部的基本概念。
2.JVM内部的基本概念
Java虚拟机内部有一些概念,全部列举是不现实的,太繁琐也没有意义。除非您真的想自己去做一个JVM。笔者只列举部分概念:
首先我们来看一个叫做ReturnAddress的变量,它是JVM用来存储方法出口或者说进行跳转的依据,把任何地址存入这个变量就一定会按照这个地址来跳转。我们需要注意的就是finally有比方法return更高的赋值给ReturnAddress的优先级。同时存在方法return和finallyreturn的话,一定是按照finally里面的return为准。
JVM有自己的Heap,能被所有线程共享,存储着所有的对象,内存是动态被分配的。对于每个线程,拥有自己的Stack,栈里面存储的单位叫做Frame(桢)。桢里面就记录着零时变量、对象引用地址、方法返回值等数据。JVM还有一个叫做MethodArea的地方,存储着一段一段的可执行代码,每一段就是一个方法体,也能被所有线程共享。所以我们说一个线程其实从run方法跑起来,跟它的类中声明的其他方法是两个概念。因为其他的方法包括的所有的对象,这个时候都充当为资源被线程使用。
JVM有自己管理内存的方案,因为它具有文件系统的功能,我们可以看成一个小型的数据库,内部有许许多多不同的表。表的字段可能是另外一张表的地址,也可以直接就是一个存储数据值的地址值。JVM所有对运行时候类的解析验证计算等管理工作,实际上都是在管理这些表的变动,如果我们从数据库的角度来看,JVM所做的就是根据你的代码来操作那么多个表***返回给你结果的过程。里面的表结构包括class的表、field表、method表、attribute表等。本节关于JVM实现机制的内容介绍到这里,请关注本文其他相关报道。
【编辑推荐】