jvm学习笔记二,虚拟机执行子系统

文件类结构

注意:任何一个Class文件都对应着唯一一个类或接口的定义信息,但是反过来说,类或接口并不一定都得定义在文件里(例如类或接口也可以通过类加载器直接生成)

Class文件是一组以8位字节为基础单位的二进制流,各个数据项目严格按照顺序紧凑的排列在Class文件之中,中间没有添加任何分隔符,这使得整个Class文件中存储的内容几乎是程序运行的必要数据,没有空隙存在。当遇到需要占用8位字节以上空间的数据项时,则会按照高位在前的方式分割成若干个8位字节进行存储。

Class文件格式采用一种类似于C语言结构体的伪结构来存储数据,它只有两种数据类型:无符号数和表,u1,u2,u4,u8分表代表1个字节、2个字节、4个字节、8个字节,无符号数可以用来描述数字、索引引用、数量值或者按照UTF-8编码构成字符串值。表是由多个无符号数或其他表作为数据项构成的复合数据类型,整个Class文件本质就是一张表。

start:每个Class文件的头4个字节称为魔数(作用是确定这个文件是否为一个能被虚拟机接受的Class文件),魔数的第四个字节是Class文件的版本号,第5个和第6个字节是次版本号,第7和第8个字节是主版本号。

主次版本号之后是常量池的入口(主要存放两大常量:字面量和符号引用,符号引用又包括(类和接口的全限定名、字段的名名称和描述符、方法的名称和描述符))

常量池之后的两个字节代表访问标志(识别这个Class是类还是接口,是否是public、abstract、类是否被生命为final)

类索引、父类索引与接口索引集合字段表集合方法表集合属性表集合 :end

字节码指令简介:

java虚拟机的指令是由一个字节长度的、代表着某种特定操作含义的数字(称为操作码,Opcode)以及跟随其后的零至多代表此操作所需参数(称为操作室,Operands)而构成。

===========================================================================================

虚拟机类加载机制

类加载过程:

->加载 -> 连接(验证,准备,解析) -> 初始化(执行代码块,静态变量) 

类加载器

(虚拟机设计团队把类加载器阶段中的“通过一个类的全限定名来获取描述此类的二进制字节流” 这个动作放到java虚拟机外部去实现,以便让应用程序自己决定如何获取所需要的类,这个动作称为“类加载器”)

1.类与类加载器

比较两个类是否“相等”,只有在这两个类是由同一个类加载器加载的前提下才有意义,否则,即使这两个类来源于同一个Class文件,被同一个虚拟机加载;他们也必定不相等。

2.双亲委派模型

(从虚拟机的角度讲,只有两种不同的类加载器:一种是启动类加载器,这个类加载器是C++实现,是虚拟机自身的一部分;另一种就是所有其他类加载器(扩展类加载器、应用程序类加载器),这些类加载器由Java 语言实现,独立于虚拟机外部,并且都继承自抽象类java.lang.ClassLoader)

一个类加载器收到加载请求它不会先加载自己,而是把这个请求委派给父类去加载,当父类无法加载的时候,子类才会自己尝试去加载

(自定义加载器 -> 应用类加载器 -> 扩展类加载器 -> 启动类加载器(从左到右,委派给最右边的启动类加载器执行,启动类加载位于顶层))

自己写一个public class String {} ,这个类可以正常编译,但是不能够加载,因为在启动类加载器已经有String这个类了

3.破坏双亲委派模型

i.  java.lang.ClassLoader添加一个新的protected方法findClass

ii. 基础类需要回调用户代码,例如:JNDI,之后设计了“线程上下文类加载器”

iii.用户追求程序动态性(代码热替换、模块热部署),因为有些生产环境的系统不能轻易重启

===========================================================================================

虚拟机字节码执行引擎

运行时栈帧结构

局部变量表、操作数栈、动态连接、方法返回地址、附加信息

(栈帧是用于支持虚拟机进行方法调用和方法执行的数据结构,它是虚拟机运行时数据区的虚拟机栈的栈元素。栈帧存储了方法的局部变量表、操作数栈、动态连接和方法返回地址等信息。每一个方法从调用开始至执行完成的过程,都对应着一个栈帧在虚拟机栈里面从入栈到出栈的过程。)

方法调用

解析、分派、动态类型语言支持

基于栈的字节码解释执行引擎

解释执行、基于栈的指令集与基于寄存器的指令集、基于栈的解释器执行过程

===========================================================================================

类加载及执行子系统的案例与实战

我们没有办法把15寸显示器变成24寸的,但是却可以跨越JDK版本之间的沟壑,把JDK1.5中编写的代码放到JDK1.4或者1.3的环境中去部署使用。为了解决这个问题,一种名为“Java逆向移植”的工具应运而生,Retrotranslator是这类工具中比较出色的一个。

===========================================================================================

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值