程序员从宏观、微观角度浅析JVM虚拟机!
副标题[/!--empirenews.page--]
1.问题
2.关键词 编译,魔数,常量池,字面量,数据表,堆栈,方法区,程序计数器,内存引用,内存溢出,垃圾回收器,新生区,永久区,指令集 3.全文概要 本文将从宏观及微观角度来介绍类文件结构、虚拟机加载类文件机制,类文件生命周期及字节码加载引擎,更加立体的加深对虚拟机工作的认识。 4.CLASS文件结构分析 从我们学习JAVA语言的第一天起,就执行过JAVA/JAVAC命令。JAVAC就是把我们写好的后缀为.java的文本文件编译成后缀为.class的字节码文件。上一章我们介绍代码本质的时候就了解到JAVA语言的语法元素。java文件我们可以通过文本编辑器打开,里面也是我们熟悉的java代码,符合了java语言的语法规范。但是对于class里面的内容,我们要陌生很多。上一章我们知道代码通过编译器翻译成机器指令,那class文件会不会也是java虚拟机翻译成的指令呢? 其实当java文件被编译成class文件后,就跟java语言没什么关系了。指令执行引擎是JVM虚拟机,其他编程语言,比如Scala,Python等都可以编译成class文件,然后放到JVM来执行。这么说来,我们更加有必要探究class文件的本质了。 4.1 CLASS文件示例 我们先从微观的角度来介绍class文件的结构。先写一个简单的java文本文件,然后编译成class文件,来观察class的结构组成。 先定义一个接口文件,Add.java文件如下:
由于存在包名定义我们需要建好com/lzh/jvm的文件目录,然后在当前目录先后编译com/lzh/jvm/Add.java文件和com/lzh/jvm/AddImpl.java文件。得到了Add.class文件和AddImpl.class文件。 Add.java二进制文件: Add.class二进制文件: AddImpl.java二进制文件: AddImpl.class二进制文件: 以上四个图是用WinHex二进制编辑工具打开的,左边是文件的二进制编码,右边是ASCII标准编码,所以只能表示英式键盘上的字符,出现中文的话则显示乱码。为了阅读方便,工具展示的是16进制的格式,两个16进制的编码表示一个字节空间(8位)。 直观上我们可以看出来java文件占用的存储空间比class要少很多,这也符合我们上一章介绍的代码翻译过程。本质上计算机并不认识java文件里面的内容,java属于高级语言,里面的语法更为接近人类的语言,但是对于计算机来说全难以理解。所以需要把java文件的内容翻译成jvm认识的文件格式。 高级语言高度抽象了语言元素,翻译为机器指令则要花费更多的“口舌”来指导计算机一步步执行代码语句。下一节我们来解释class文件的结构,从而理解jvm如何理解执行class的内容。 4.2 class文件结构说明 本节我们将以上图给的AddImpl.class为例子来介绍类的结构。从结构上来看,class文件只存放两种类型数据,分别为基础字段和表。
4.2.1 魔数 用于判断文件类型,通常我们以文件后缀来判别文件类型,但是如果修改后缀就会导致安全问题。class以4个字节的空间作为开端,来标明class的类型,CA FE BA BE表示class类型的文件。 4.2.2 版本数 魔数后面紧接着4个字节表示jdk版本号。
4.2.3 常量池 常量池顾名思义是用于存放字符串常量,字符串常量包含:
(编辑:晋中站长网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |