Java基础:类文件结构及类加载
Class文件结构
- 魔数 4bits 确定该文件是否是可接受的Class文件(0xCAFEBABE)
- 版本号 4bits 包括次版本号和主版本号
- 常量池 包括字面量(文本字符串,声明为final的常量值)和符号引用(类和接口的全限定名,字段的名称和描述符,方法的名称和描述符)
- 访问标志 2bits 标志识别类或者接口层次的访问信息,如类是否为public,是否为abstract,是否为final,是Class还是Interface。
- 类索引 父索引与接口索引集合 用于确定这个类的继承关系
- 字段表集合 包括用于描述接口或类中声明得变量,包括public private protected static final volatile transient synthetic(字段是否为编译器自动产生) enum,以及变量简要名称和类型描述符(基本类型,数组)。
- 方法表集合 类似字段表集合,包括前缀,简要名称,类型描述符,不包含方法中的代码。
- 属性表 存放多种属性,如方法中的代码存在Code属性中,操作栈深度最大值,exception等。
类加载机制
类加载的整个生命周期: 加载,验证,准备,解析,初始化,使用,卸载
对类初始化的情况
- new关键字实例化对象,读取设置类的静态字段(非final修饰),调用一个类的静态方法
- 反射调用
- 初始化一个类时,若父类没有初始化,则先初始化父类
- 虚拟机启动时,用户指定的主类
- java.lang.invoke.MethodHandle的解析结果是一个静态方法,则需要先初始化方法对应的类
加载
- 通过一个类的全限定名来获取定义此类的二进制字节流。
- 将字节流代表的静态存储结构转化为方法区的运行时结构。
- 内存中生成一个代表这个类的java.lang.Class对象,作为方法区这个类的各种数据访问入口。
验证
- 文件格式验证:对Class文件进行格式校验。是否以魔数开头,主次版本号是否可处理,常量池中常量是否全支持...
- 元数据验证:对字节码描述的信息进行语义分析。这个类是否有父类,父类是否不允许继承,字段是否与父类矛盾...
- 字节码验证:对数据流和控制流进行分析。对方法体进行校验分析,如类型校验等。
- 符号引用验证:对符号引用进行校验保证其可转换为直接引用。
准备
- 为变量分配内存。(仅包含类变量,不包括实例变量)
- 为变量设置初始值。(仅设置类型对应的默认值,不赋值)
解析
解析阶段虚拟机将常量池内的符号引用替换为直接引用。
符号引用用一组符号描述所引用的目标,使用时可以无歧义的定位到目标。
直接引用可以是直接指向目标的指针,相对偏移量,或能够间接定位到目标的句柄。不通虚拟机中翻译出的直接引用一般不同。
初始化
初始化是类加载过程中最后一步。初始化接端是执行类构造器<clinit>()方法的过程。该方法是编译器自动收集类中所有类变量的赋值动作和静态语块(static{})中的语句合并而成的,其收集顺序取决于源文件中的出现顺序。虚拟机会保证子类的<clinit>()执行前,父类的<clinit>()已经执行过,因此不需要显示的调用。多线程环境中,<clinit>()方法使用悲观锁阻塞,并保证只被运行一次。
类加载器
上述过程中,第一步加载中,通过一个类的全限定名来获取描述此类的二进制字节流这个机制放在Java虚拟机外部实现,实现这个动作的代码模块称为类加载器。任意一个类,都需要由它的加载器和这个类本身一同确立其在Java虚拟机中的唯一性,每一个类加载器都拥有一个独立的类命名空间。两个类是否相等,只在这两个类是由同一个类加载器加载的前提下才有意义,否则必顶步等。(相等指equals()方法,instanceof关键字等)
双亲委派模型
从JVM角度,只存在两种不同的类加载器:启动类加载器,C++实现,JVM一部分;其他类加载器,Java实现,独立于类,继承java.lang.ClassLoader。
启动类加载器负责将\lib中JVM识别的类库加到JVM内存中(如名字为rt.jar),启动类加载器无法被Java程序直接引用,用户自定义加载器时,把加载请求委派给引导类加载器只需要使用null替换。
其他类加载器包括扩展类加载器和应用程序类加载器,前者负责加载\lib\ext目录中的类库,后者是ClassLoader::getSystemClassLoader()的返回值,负责加载用户类路径上指定的类库,没有自定义过类加载器,这个加载器就是程序中默认的加载器。
这些加载器的关系如图所示
双亲委派模式要求除了顶层的启动类加载器,其余的类加载器都应该有自己的父加载器。其工作过程中,如果一个类加载器收到了类加载的请求,它首先不回去尝试加载这个类,而是把这个请求委派给父类加载器去完成,每一个层级的加载器都是如此,因此所有的加载请求最终都应该传到顶层的启动类加载器中,只有当父加载器反馈自己无法完成这个加载请求时,子加载器才会尝试自己去加载。该模式保证了Java程序中的稳定性,如,重写rt.jar类中的类,不会有编译错误,但无法被加载。
双亲委派模型不是强制性约束模型,由于它的某些缺陷(如基础类要调用回用户的代码),某些标准服务打破了它,如JNDI服务,用于对资源进行集中管理和查找,JNDI使用了线程上下文类加载器。Java中所有涉及SPI的加载动作都采用这种方式,如JDBC。另外,模块热部署也破坏了双亲委派模型。
Java基础:类文件结构及类加载的更多相关文章
- 深入理解java虚拟机【Java Class类文件结构】
Java语言从诞生之时就宣称一次编写,到处运行的跨平台特性,其实现原理是源码文件并没有直接编译成机器指令,而是编译成Java虚拟机可以识别和运行的字节码文件(Class类文件,*.class),字节码 ...
- (转)《深入理解java虚拟机》学习笔记5——Java Class类文件结构
Java语言从诞生之时就宣称一次编写,到处运行的跨平台特性,其实现原理是源码文件并没有直接编译成机器指令,而是编译成Java虚拟机可以识别和运行的字节码文件(Class类文件,*.class),字节码 ...
- 第31节:Java基础-类与对象
前言 Java基础-类与对象,方法的重载,构造方法的重载,static关键字,main()方法,this关键字,包,访问权限,类的继承,继承性,方法的重写,super变量. 方法的重载:成员方法的重载 ...
- 深入理解Java虚拟机学习笔记(三)-----类文件结构/虚拟机类加载机制
第6章 类文件结构 1. 无关性 各种不同平台的虚拟机与所有平台都统一使用的程序存储格式——字节码(即扩展名为 .class 的文件) 是构成平台无关性的基石. 字节码(即扩展名为 .class 的文 ...
- Java基础---Java---基础加强---类加载器、委托机制、AOP、 动态代理技术、让动态生成的类成为目标类的代理、实现Spring可配置的AOP框架
类加载器 Java虚拟机中可以安装多个类加载器,系统默认三个主要类加载器,每个类负责加载特定位置的类:BootStrap,ExtClassLoader,AppClassLoader 类加载器也是Jav ...
- Class类文件结构、类加载机制以及字节码执行
一.Class类文件结构 Class类文件严格按照顺序紧凑的排列,由无符号数和表构成,表是由多个无符号数或其他数据项构成的符合数据结构. Class类文件格式按如下顺序排列: 类型 名称 数量 u ...
- Java虚拟机-类文件结构
目录 类文件结构 Class类文件的结构 魔数与Class文件的版本 常量池 访问标志 类索引.父类索引和接口索引集合 字段表集合 方法表集合 属性表集合 完整结构描述 实例 源码 Class文件 分 ...
- JAVA基础知识之JVM-——自定义类加载器
JVM中除了根加载器之外其他加载器都是ClassLoader的子类实例, 可以通过扩展ClassLoader的子类,通过重写方法来实现自定义的类加载器. ClassLoader中有两个关键的方法如下, ...
- jvm虚拟机笔记<三> 类文件结构与类加载机制
java虚拟机具有语言无关系,它只和“class文件“这种特定的二进制文件格式绑定. 不同语言的编译器将对应的程序编译成字节码文件(*.class),送给jvm执行. class文件本质上就是一张表, ...
随机推荐
- 生活 RH阴性血 AB型
这个血型很稀有,外国多些,中国很少. ABO型:A.B.AB.O RH血型系统:阴性,阳性 RH阴性血,被称为熊猫血,估计是稀有吧,阴性血缺抗D,我老婆的血型抗原好像是:ccee,大部分汉族人都有抗D ...
- python3 结束子线程
最近公司内部网络经常出问题,奇慢无比,导致人脸检测程序在下载图片时经常卡住,为了不影响数据的核对, 决定在网络不佳图片下载超时后放弃下载,继续执行后续程序. 于是整理出解决思路如下: 1.在线程中完成 ...
- 洛谷 P5461 赦免战俘 题解
P5461 赦免战俘 题目背景 借助反作弊系统,一些在月赛有抄袭作弊行为的选手被抓出来了! 题目描述 现有 \(2^n\times 2^n (n\le10)\) 名作弊者站成一个正方形方阵等候 kkk ...
- 记一次清理缓存的小事情(chrome) chrome下清理缓存不生效的问题
记一次清理缓存的小事情(chrome) chrome下清理缓存不生效的问题 前端开发中会经常涉及清理缓存的事情. 在一次开发后, 需要清理缓存,一个哥们怎么清理都不生效, 于是向我求救. 在我看了下后 ...
- Mac laravel: command not found
如果用的oh-my-zsh 安装laravel 提示找不到.可以试试下面的 export PATH=$HOME/bin:/usr/local/bin:~/.composer/vendor/bin:$P ...
- 【洛谷】P3537 [POI2012]SZA-Cloakroom
题目描述 有n件物品,每件物品有三个属性a[i], b[i], c[i] (a[i]<b[i]). 再给出q个询问,每个询问由非负整数m, k, s组成,问是否能够选出某些物品使得: 1. ...
- 膜态沸腾UDF【转载】
膜态沸腾的UDF,添加注释.其中获取VOF梯度的方法详见前面的日志,其中很多宏无法通过UDF手册查阅, 蒸汽相中的质量源项的一般形式为: 式中: 通过一阶近似,热流之差可表达为: 式中: 通过此近似, ...
- UDP如何实现可靠传输
概述 UDP不属于连接协议,具有资源消耗少,处理速度快的优点,所以通常音频,视频和普通数据在传送时,使用UDP较多,因为即使丢失少量的包,也不会对接受结果产生较大的影响. 传输层无法保证数据的可靠传输 ...
- [XLua]热更新四部曲视频教程+示例源码
基于Unity2017 xLua是由腾讯维护的一个开源项目,xLua为Unity. .Net. Mono等C#环境增加Lua脚本编程的能力,借助xLua,这些Lua代码可以方便的和C#相互调用.自20 ...
- winddows rabbitmq安装与配置
RabbitMQ是一个在AMQP协议标准基础上完整的,可复用的企业消息系统.它遵循Mozilla Public License开源协议,采用 Erlang 实现的工业级的消息队列(MQ)服务器,Rab ...