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基础:类文件结构及类加载的更多相关文章

  1. 深入理解java虚拟机【Java Class类文件结构】

    Java语言从诞生之时就宣称一次编写,到处运行的跨平台特性,其实现原理是源码文件并没有直接编译成机器指令,而是编译成Java虚拟机可以识别和运行的字节码文件(Class类文件,*.class),字节码 ...

  2. (转)《深入理解java虚拟机》学习笔记5——Java Class类文件结构

    Java语言从诞生之时就宣称一次编写,到处运行的跨平台特性,其实现原理是源码文件并没有直接编译成机器指令,而是编译成Java虚拟机可以识别和运行的字节码文件(Class类文件,*.class),字节码 ...

  3. 第31节:Java基础-类与对象

    前言 Java基础-类与对象,方法的重载,构造方法的重载,static关键字,main()方法,this关键字,包,访问权限,类的继承,继承性,方法的重写,super变量. 方法的重载:成员方法的重载 ...

  4. 深入理解Java虚拟机学习笔记(三)-----类文件结构/虚拟机类加载机制

    第6章 类文件结构 1. 无关性 各种不同平台的虚拟机与所有平台都统一使用的程序存储格式——字节码(即扩展名为 .class 的文件) 是构成平台无关性的基石. 字节码(即扩展名为 .class 的文 ...

  5. Java基础---Java---基础加强---类加载器、委托机制、AOP、 动态代理技术、让动态生成的类成为目标类的代理、实现Spring可配置的AOP框架

    类加载器 Java虚拟机中可以安装多个类加载器,系统默认三个主要类加载器,每个类负责加载特定位置的类:BootStrap,ExtClassLoader,AppClassLoader 类加载器也是Jav ...

  6. Class类文件结构、类加载机制以及字节码执行

    一.Class类文件结构 Class类文件严格按照顺序紧凑的排列,由无符号数和表构成,表是由多个无符号数或其他数据项构成的符合数据结构. Class类文件格式按如下顺序排列:   类型 名称 数量 u ...

  7. Java虚拟机-类文件结构

    目录 类文件结构 Class类文件的结构 魔数与Class文件的版本 常量池 访问标志 类索引.父类索引和接口索引集合 字段表集合 方法表集合 属性表集合 完整结构描述 实例 源码 Class文件 分 ...

  8. JAVA基础知识之JVM-——自定义类加载器

    JVM中除了根加载器之外其他加载器都是ClassLoader的子类实例, 可以通过扩展ClassLoader的子类,通过重写方法来实现自定义的类加载器. ClassLoader中有两个关键的方法如下, ...

  9. jvm虚拟机笔记<三> 类文件结构与类加载机制

    java虚拟机具有语言无关系,它只和“class文件“这种特定的二进制文件格式绑定. 不同语言的编译器将对应的程序编译成字节码文件(*.class),送给jvm执行. class文件本质上就是一张表, ...

随机推荐

  1. Cogs 1708. 斐波那契平方和(矩阵乘法)

    斐波那契平方和 ★★☆ 输入文件:fibsqr.in 输出文件:fibsqr.out 简单对比 时间限制:0.5 s 内存限制:128 MB [题目描述] ,对 1000000007 取模.F0=0, ...

  2. P3388 【模板】割点(割顶)&& 桥

    题目背景 割点 题目描述 给出一个n个点,m条边的无向图,求图的割点. 输入输出格式 输入格式: 第一行输入n,m 下面m行每行输入x,y表示x到y有一条边 输出格式: 第一行输出割点个数 第二行按照 ...

  3. 性能测试学习第十天-----性能案例分析之CPU消耗过高&响应时间较长

    一.现象  /pinter/case/cpu?type=1   使用google的gjson.tojson性能较差    type=2 使用性能好的阿里巴巴的fastjson库 压测过程中,发现应用服 ...

  4. CPU突然飙升到300%,Dubbo活动线程数直接飙到1000

    转:https://mp.weixin.qq.com/s/-lSiVDfqYrKk_w-xitYBhA 背景:新功能开发测试完成后,准备发布上线,当发布完第三台机器时,监控显示其中一台机器CPU突然飙 ...

  5. QT中显示动画

    在QT中要显示GIF图片,不能通过单单的添加部件来完成.还需要手动的编写程序.工具:QT Creator新建一个工程,我们先在designer中,添加一个QLabel部件. 将QLabel拉成适当大小 ...

  6. cmd命令 taskkill

    netstat -ano|findstr " tasklist|findstr " taskkill /pid taskkill 命令: // 描述: 结束一个或多个任务或流程. ...

  7. http code 有的意思

      http code 有的意思,发现了一个图,感觉挺有意思的.   文章来源:刘俊涛的博客 欢迎关注公众号.留言.评论,一起学习. _________________________________ ...

  8. openstack kvm cannot set up guest memory 'pc.ram': Cannot allocate memory

    Kvm:启动报错:error: internal error: process exited while connecting to monitor: 2018-11-12T01:47:14.9933 ...

  9. phpstorm 使用xdebug断点

    1.下载对应版本 xdebug 下载地址:https://download.csdn.net/download/q2104574/11185239 比如你用的php7.0.12以上的版本,xdebug ...

  10. kafka 的server.properties

    # Licensed to the Apache Software Foundation (ASF) under one or more # contributor license agreement ...