【深入理解JAVA虚拟机】第三部分.虚拟机执行子系统.1.类文件结构
无关性
无关性的体现有两个方面:
1、平台无关性:可在不同的操作系统和机器指令集上执行,可在不同厂商的虚拟机平台上执行。
2、语言无关性:用不同编程语言写出的代码编译生成的文件都可以运行。
实现思想:
面向接口,定义虚拟机和编译器之间的接口规范。也就是编译后文件的存储格式——字节码(ByteCode)。
任意一种编程语言,只要生成符合存储格式规范的Class文件,就可以被任意虚拟机执行。
Class文件结构
Class文件结构是在《Java虚拟机规范》中定义的。
Class文件的存储结构类似于C语言的struct。
Class文件是一组以8位字节为基础单位的二进制流,各个数据项目严格按照顺序紧凑地排列在Class文件之中,中间没有添加任何分隔符,这使得整个Class文件中存储的内容几乎全部是程序运行的必要数据,没有空隙存在。 当遇到需要占用8位字节以上空间的数据项时,则会按照高位在前[1]的方式分割成若干个8位字节进行存储。
Class文件中只有两种类型:无符号数和表。表是无符号数和表表的集合。
Magic Number : 每个Class文件的头4个字节称为魔数(Magic Number),它的唯一作用是确定这个文件是否为一个能被虚拟机接受的Class文件。 固定为 0xCAFEBABE
第5和第6个字节是次版本号(Minor Version),第7和第8个字节是主版本号(Major Version)
常量池(constant_pool) 主要存放两大类常量:字面量(Literal)和符号引用(Symbolic References)。
字面量比较接近于Java语言层面的常量概念,如文本字符串、 声明为final的常量值等。
符号引用则属于编译原理方面的概念,包括了下面三类常量:类和接口的全限定名(Fully Qualified Name),字段的名称和描述符(Descriptor),方法的名称和描述符
访问标志(access_flags) 用于识别一些类或者接口层次的访问信息,包括:这个Class是类还是接口;是否定义为public类型;是否定义为abstract类型;如果是类的话,是否被声明为final等。
类索引(this_class)和父类索引(super_class) 接口索引集合(interfaces)
字段表(field_info)用于描述接口或者类中声明的变量。
方法表集合 (methods)
属性表(attribute_info) 在Class文件、 字段表、 方法表都可以携带自己的属性表集合,以用于描述某些场景专有的信息。
Code属性
首先,这是一个属性,位于属性表里面。
Java程序方法体中的代码经过Javac编译器处理后,最终变为字节码指令存储在Code属性内。
Code属性是Class文件中最重要的一个属性,如果把一个Java程序中的信息分为代码(Code,方法体里面的Java代码)和元数据(Metadata,包括类、 字段、 方法定义及其他信息)两部分,那么在整个Class文件中,Code属性用于描述代码,所有的其他数据项目都用于描述元数据。
字节码指令
Java虚拟机的指令由一个字节长度的、 代表着某种特定操作含义的数字(称为操作码,Opcode)以及跟随其后的零至多个代表此操作所需参数(称为操作数,Operands)而构成。
由于Java虚拟机采用面向操作数栈而不是寄存器的架构(这两种架构的区别和影响将在第8章中探讨),所以大多数的指令都不包含操作数,只有一个操作码。
单字节的优势:短小精悍,存储小,传输快。缺点:解析慢,扩展少。
在Java虚拟机的指令集中,大多数的指令都包含了其操作所对应的数据类型信息。 如:iload,fload,dload。
大多数对于boolean、 byte、 short和char类型数据的操作,实际上都是使用相应的int类型作为运算类型
操作类型:加载和存储指令 ,运算指令 ,类型转换指令 ,对象创建与访问指令 ,操作数栈管理指令 ,控制转移指令 ,方法调用和返回指令 ,异常处理指令 ,同步指令 。
一个字节码指令的例子:
void onlyMe(Foo f){
synchronized(f){
doSomething();
}
}
编译后生成的字节码:
Method void onlyMe(Foo)
0 aload_1//将对象f入栈
1 dup//复制栈顶元素(即f的引用)
2 astore_2//将栈顶元素存储到局部变量表Slot 2中
3 monitorenter//以栈顶元素(即f)作为锁,开始同步
4 aload_0//将局部变量Slot 0(即this指针)的元素入栈
5 invokevirtual#5//调用doSomething()方法
8 aload_2//将局部变量Slow 2的元素(即f)入栈
9 monitorexit//退出同步
10 goto 18//方法正常结束,跳转到18返回
13 astore_3//从这步开始是异常路径,见下面异常表的Taget 13
14 aload_2//将局部变量Slow 2的元素(即f)入栈
15 monitorexit//退出同步
16 aload_3//将局部变量Slow 3的元素(即异常对象)入栈
17 athrow//把异常对象重新抛出给onlyMe()方法的调用者
18 return//方法正常返回
Exception table:
FromTo Target Type
4 10 13 any
13 16 13 any
是不是很像汇编? 这样理解也应该可以:字节码就是虚拟机上的汇编语言。
再总结一下
class文件格式,是在JVM虚拟机和各种语言编译器之间的接口。
只要符合这个接口规范,任何语言的任何编译器,编出来的class文件,都可以在任何JVM虚拟机上运行。
Class文件分两部分:1、元数据,2、字节码指令集。
这些内容与硬件、 操作系统及具体的Java虚拟机实现之间是完全独立的,虚拟机实现者可能更愿意把它们看做是程序在各种Java平台实现之间互相安全地交互的手段。
虚拟机实现的方式主要有以下两种:
将输入的Java虚拟机代码在加载或执行时翻译成另外一种虚拟机的指令集。 -- 好处:适应于各种硬件环境。
将输入的Java虚拟机代码在加载或执行时翻译成宿主机CPU的本地指令集(即JIT代码生成技术)。 -- 好处:提升热点函数的执行速度。 HotSpot的命名即来于此。
【深入理解JAVA虚拟机】第三部分.虚拟机执行子系统.1.类文件结构的更多相关文章
- 深入理解Java内存模型中的虚拟机栈
深入理解Java内存模型中的虚拟机栈 Java虚拟机在执行Java程序的过程中会把它所管理的内存划分为若干个不同的数据区域,这些区域都会有各自的用途,以及创建和销毁的时间,有的区域会随着虚拟机进程的启 ...
- (4) 深入理解Java Class文件格式(三)
转载:http://blog.csdn.net/zhangjg_blog/article/details/21557357 首先, 让我们回顾一下关于class文件格式的之前两篇博客的主要内容. 在 ...
- 【由浅入深理解java集合】(三)——集合 List
第一篇文章中介绍了List集合的一些通用知识.本篇文章将集中介绍List集合相比Collection接口增加的一些重要功能以及List集合的两个重要子类ArrayList及LinkedList. 一. ...
- java虚拟机(三)-- 虚拟机类加载机制
1.类加载的时机:类从被加载到虚拟机内存中开始,到卸载出内存为止.包含以下几个阶段: 1.加载 2.验证 3.准备 4.解析 5.初始化 6.使用 7.卸载 2.类加载器的种类 1.启动类加载器:这个 ...
- 深入理解Java AIO(三)—— Linux中的AIO实现
我们调用的Java AIO底层也是要调用OS的AIO实现,而OS主要也就Windows和Linux这两大类,当然还有Solaris和mac这些小众的. 在 Windows 操作系统中,提供了一个叫做 ...
- 深入理解JAVA集合系列三:HashMap的死循环解读
由于在公司项目中偶尔会遇到HashMap死循环造成CPU100%,重启后问题消失,隔一段时间又会反复出现.今天在这里来仔细剖析下多线程情况下HashMap所带来的问题: 1.多线程put操作后,get ...
- 深入理解java:1.2. 字节码执行引擎
执行引擎是Java虚拟机的核心组成部分之一. 首先,想想C++和Java在编译和运行时到底有啥不一样? 下图左边,C++发布的就是机器指令, 而下图右边Java发布的是字节码,字节码在运行时通过JVM ...
- Java基础---IO(三)--IO包中的其他类
第一讲 对象序列化 一.概述 将堆内存中的对象存入硬盘,保留对象中的数据,称之为对象的持久化(或序列化).使用到的两个类:ObjectInputStream和ObjectOutputStrea ...
- java判断手机号三大运营商归属的工具类
package com.tymk.front.third; import java.util.regex.Pattern; public class OperatorsUtil { /** * 中国电 ...
随机推荐
- JUnit快速入门
一.一个简单的Junit测试流程: 1.在项目中导入junit-4.7.jar包, 方法:右击项目,选择Build Path->Configure Build Path->Librarie ...
- Flexbox 完全指南
Flexbox 完全指南 我不是这篇文章的原创作者,我只是好文章的搬运工.原文地址 A Complete Guide to Flexbox 应用于 flex container 的属性 display ...
- 【ExtJS】FormPanel 布局(二)
周末2天好好学习了下布局,现在都给实现了吧. 5.border布局: Border布局将容器分为五个区域:north.south.east.west和center.除了center区域外,其他区域都需 ...
- plpgsql insert 性能 测试
有时需要执行一些sql脚本,带逻辑控制语句,又不想用高级语言C#.Java之类的,可以直接用plpgsql,类似于Oracle的plsql. do language 'plpgsql' $$ decl ...
- CentOS7部署.Net Core2.0站点(中)
继续上篇的内容,本篇来学习下nginx的配置和守护进程supervisor的使用. 一.Nginx安装及配置 (1)安装nginx sudo yum install epel-release #添加源 ...
- (C++学习)关于CString的一些疑问
#include <iostream> #include <string> #include <afx.h> #include <vector> usi ...
- springboot mybatis 使用多数据源
SpringBoot系列博客目录,含1.5.X版本和2.X版本 springboot2.0正式版发布之后,很多的组件集成需要变更了,这次将多数据源的使用踩的坑给大家填一填.当前多数据源的主要为主从库, ...
- 在线HTML文档编辑器使用入门之图片上传与图片管理的实现
在线HTML文档编辑器使用入门之图片上传与图片管理的实现: 官方网址: http://kindeditor.net/demo.php 开发步骤: 1.开发中只需要导入选中的文件(通常在 webapp ...
- Java 不可变类
Java 不可变类 immutable object 不可变类是指这个类的实例一旦创建完成后,就不能改变其成员变量值. 如JDK内部自带的很多不可变类:Interger.Long和String等. * ...
- CSS之inline和inline-block
inline-block 控制台-代码: PS:inline-block是让元素以内联形式存在,也就是不是块级,但是表现起来(又具有块级元素的高度)--也就是可以调高度(margin或者padding ...