class文件格式
平台中立的格式二进制,通常以文件形式存储
定义了类接口的表现形式
虚拟机可操作的类型
为原始类型(原生类型或者基本类型)和引用类型
原始值和引用值 会用于变量赋值、参数传递、方法返回、运算操作
运行机字节码本身就可以确定操作数的类型 iadd ladd fadd daadd
原始的类型包括 数值类型、boolean类型和returnAddress
数值类型 整数类型 byte(-128 127) short int long char float double
boolean 类型 在编译之后会使用int类型替代
returnAddress 指向一个操作吗的指针
引用类型 类类型 数组类型 接口类型
程序运行时使用到的数据区
运行时数据区
- pc寄存器
线程私有
任意时刻一个虚拟机只会执行一个方法的代码
当前方法
是native,pc寄存器的值是undefined
不是native,指向虚拟机正在执行的字节码指令的地址
容量至少能存一个returnAddress类型的数据,或者一个平台相关的本地指针的值
- Java虚拟栈
存储栈帧Frame
类似于C 用于存储一些局部变量和一些尚未算好的结果
栈帧可在堆中分配
可以固定大小,也可以动态计算
会抛出
请求分配的栈容量超过允许的最大容量异常StackOverFlowError
栈动态扩容没有内存创建 OutOfMeomoryError
- Java堆
每个线程共享的运行内存,类实例和数组对象分配的区域
虚拟机启动已经分配 存了gc管理的对象,无法显示销毁。
可以固定,可以动态
OutOfMemoryErr
- 方法区
提供了各个线程共享的内存区域
存储了类的结构信息(运行时常量池,方法区,字段,方法数据,构造函数,普通方法的字节码)
堆的逻辑组成部分 可以选择不实现垃圾收集与压缩
也会抛出OufOfMemoryError
runtimeconstantpool
- 本地方法栈
也会有异常
- 补充
Frame 存储数据和部分过程结果的数据结构,也处理动态链接和方法返回值和异常分派 声明周期随方法
栈帧有局部变量表,操作数栈和指向当前方法所属类的运行时常量池的引用
活动的栈帧叫当前栈帧 当前方法 当前类
局部变量表 存储于类或者接口的二进制之中 方法的code
一个方法如果要调用其他方法,需要用符号引用表示
动态链接的作用是符号引用变为实际方法的直接引用
栈帧内部包含一个指向当前方法所在类型的运行时常量池的引用
类的加载过程 就是完成解析未被解析的符号应用
由于对其他的类进行晚期绑定 那么这些类发生变化也不会影响调用他们的方法、、、
栈帧也承担着恢复调用者的状态的责任 局部变量表 操作数栈 和递增PC
无法执行 或遇见athrow字节码指令
虚拟机不规定对象内部结构的表示
//
引用 是一个指向句柄的指针 句柄有两个指针 一个是指向表格 (方法)包括一个指向Class对象的指针 另一个指针 指向分配在堆中对象实例的数据
Java虚拟机特殊支持的类
反射 reflect
加载和创建类或者接口的类
连接和初始化接口的类
安全
多线程
弱引用 ref
同步monitorenter
monitorexit
同步方法调用指令读取常量池方法中的ACC_SYNCHRONIZED
加载链接初始过程
加载根据类名找类和接口的二进制表示,并完成创建的过程
链接 将类和接口并入虚拟机运行时状态的过程
初始化 执行
虚拟机的启动
通过引导类加载器创建一个初始类完成 initial class 它由虚拟机具体实现
初始化initialclass 并调用它的main方法 之后的执行过程都是对该方法的调用开始
创建和加载
T C的方法区创建与虚拟机相匹配的内部表示
而它的创建由其他类或者接口触发 其他类在自己运行时常量池引用了C 也有可能是反射
如果不是数组类 通过累加器加载二进制完成创建
区分 数组和非数组
类加载器两种 自定义 提供的
自定义 便于扩展虚拟机功能 支持动态加载和创建
用途 网络获取动态产生或者加密文件提取
加载过程复杂
委托了
L直接创建C L这就是C的定义加载器
L 委托或直接 L是C的初始化累加器
类或接口不是由名称确认
键值对 二进制名称和定义类加载器确认的 都属于运行时包结构
类加载器L创建一个如ClassFile结构的字节数组表示C ;然后必须调用ClassLoader的defineClass方法,defineClass会让Java虚拟机使用一个算法由字节数组得到标记为N的类或者接口
L委托给L‘’ 调用L‘’的loadClass而完成( boolean)是否需要链接
链接
包括验证和准备接口,它的直接父类,父接口,元素类型
而解析符号引用是可选的
会涉及到内存结构分配
验证
确保二进制结构正确 会导致其他类或接口加载,但一定不会导致被验证或者准备。
准备
创建类或者接口的静态字段,并将它们默认和初始化
准备阶段有一个强制性加载约束。
解析过程 根据运行时常量池里的符号引用来动态决定具体的值
初始化
类或接口就是执行初始化方法
初始化条件
new getstatic putstatic invokestatic 会字段引用或者方法引用直接间接引用一个类
在初始化时需要注意多线程 线程同步和递归初始化问题
本地方法绑定
虚拟机退出的条件某个线程调用了Runtime或者System的exit方法 Runtime的halt方法