加入收藏 | 设为首页 | 会员中心 | 我要投稿 衡阳站长网 (https://www.0734zz.cn/)- 数据集成、设备管理、备份、数据加密、智能搜索!
当前位置: 首页 > 综合聚焦 > 资源网站 > 空间 > 正文

程序员从宏观、微观角度浅析JVM虚拟机!

发布时间:2019-03-21 00:12:46 所属栏目:空间 来源:架构月亮姨
导读:1.问题 JAVA文本文件如何被翻译成CLASS二进制文件? 如何理解CLASS文件的组成结构? 虚拟机如何加载使用类文件的生命周期? 虚拟机系列诊断工具如何使用? 虚拟机内存淘汰机制? 虚拟机指令集架构? 2.关键词 编译,魔数,常量池,字面量,数据表,堆栈,方法区
副标题[/!--empirenews.page--]

 1.问题

  1. JAVA文本文件如何被翻译成CLASS二进制文件?
  2. 如何理解CLASS文件的组成结构?
  3. 虚拟机如何加载使用类文件的生命周期?
  4. 虚拟机系列诊断工具如何使用?
  5. 虚拟机内存淘汰机制?
  6. 虚拟机指令集架构?
  7. 程序员从宏观、微观角度浅析JVM虚拟机!

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文件如下:

  1. package com.lzh.jvm; 
  2. public interface Add{ 
  3.  int add(int i,int j); 
  4. 再写一个接口的实现类AddImpl.java,这个基本包含我们日常经常使用的文件结构: 
  5. package com.lzh.jvm; 
  6. public class AddImpl implements Add{ 
  7.  public static final int TOP = 100; 
  8.  private String point; 
  9.  public int add(int i,int j){ 
  10.  return i + j; 
  11.  } 

由于存在包名定义我们需要建好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文件只存放两种类型数据,分别为基础字段和表。

  • 基础字段:用于描述数字,引用,数值或字符串的无符号数,类型为u1,u2,u4,u8表示占用字节数
  • 表:只有一行的可变列数的表结构,每个字段可以是基础字段或其他表的索引

4.2.1 魔数

用于判断文件类型,通常我们以文件后缀来判别文件类型,但是如果修改后缀就会导致安全问题。class以4个字节的空间作为开端,来标明class的类型,CA FE BA BE表示class类型的文件。

4.2.2 版本数

魔数后面紧接着4个字节表示jdk版本号。

  • 次版本号:前两个字段0x0000
  • 主版本号:后两个字段0x0035,转换十进制为53,对应jdk1.9

4.2.3 常量池

常量池顾名思义是用于存放字符串常量,字符串常量包含:

  • 字面量:字符串,常量
  • 引用符合:类/接口全限定名,字段/方法名称和修饰符

(编辑:衡阳站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

推荐文章
    热点阅读