Java虚拟机之Class文件

       Class文件是Java程序的二进制格式,全面描述Java类或者接口。每个Class文件只能描述一个Java类或者接口的全部信息。Class文件的特点 :1. 8位字节的二进制流;2.  按照数据项顺序存储,高位在前;3.  数据项 之间没有间隔。 Java虚拟机是通过读取和解析Class文件来执行Java程序,但是其他一些语言可以编译成Class文件在Java虚拟机上运行。因此,Java虚拟机并不关心Class来源于何种语言,只要符合Class文件的结构规范就可以执行。

       Class文件中只有两种数据类型:无符号数和表。无符号数属于基本的数据类型,以U1、U2、U4、U8来分别代表1个字节、2个字节、4个字节、8个字节的无符号数。表其实是基本数据类型和其他表组成的复合数据类型,习惯以”_info“结尾。 Class文件是按照数据项顺序存储,其数据项的信息和它们出现的顺序如下表所示

类型

名称

数量

U4

Magic

1

U2

Minor_version

1

U2

Major_version

1

U2

Constant_pool_count

1

Cp_info

Constant_pool

Constant_pool_count-1

U2

Access_flags

1

U2

This_class

1

U2

Super_class

1

U2

Interfaces_count

1

U2

Interfaces

Interfaces_count

U2

Fields_count

1

Field_info

Fields

Fields_count

U2

Methods_count

1

Method_info

Methods

Methods_count

U2

Attributes_count

1

Attribute_info

Attributes

Attributes_count


  下面对各数据项进行简要介绍:
1. 魔数(Magic Number)
    每个Class文件的头4个字节称为魔数(Magic Number),它的唯一作用是判断这个文件是否为能被虚拟机接受的Class文件,其值为0xCAFEBABE。
2. 版本号(Minor_version & Major_version)
     魔数后面的4个字节是Class文件的版本号:第5和第6是次版本号(Minior Version),第7个和第8个字节是主版本号(Major Version)。Class不同的版本,有不同的特性。如果Class文件版本号超出了Java虚拟机能够处理的范围,Java虚拟机将不会处理该 Class文件。
3. 常量池(Constant Pool)
    常量池存储了类和接口相关的常量,主要分 为两大类:字面量和符号引用。字面量比较接近于Java语言层面的常量概念,如文本字符串、被声明为final的常量值等。而符号引用则属于编译原理方面的概念,包括了下面三类常量:类和接口的全限定名;字段的名称和描述符;方法的名称和描述符。
    Class将常量 池组织为入口列表的形式。在常量池入口之前,是入口列表的计数值constant_pool_count,代表常量池的容量。constant_pool_count从1开始计数,第0项腾出来满足后面某些指向常量池的索引值的数据在特定情况下需要表达"不引用任何一个常量池项目"的意思。因此,constant_pool中入口列表的项数,等于constant_poo_count的值减1。Class文件结构中只有常量池的容量计数是从1开始的,对于其他集合类型,包括接口索引集合、字段表集合、方法表集合等的容量计数都是从0开始的。
    常量池中的许多入口都指向其他的常量池入口,而且class文件中紧随常量池的许多条目也会指向常量池的中的入口。 常量池中的每一项常量都是一个表,每个表都是从一个U1类型的tag开始,该tag代表当前对象的常量类型。11种常量类型所代表的具体含义如下表所示:


4. 访问标志(access_flags)
    access_flags展示了类或接口的几段信息。例如:访问标志指明文件中定义的是类还是接口;还定义了在类或接口的声明中,使用了哪种修饰符;类和接口是抽象的,还是公共的;类的类型可以为final,而final类不可能是抽象的;接口不能为final类型的。这些标志位的定义如下表所示:

标志名

设置后的含义

设置者

ACC_PUBLIC

0x0001

Public类型

类和接口

ACC_FINAL

0x0010

类为final类型

只有类

ACC_SUPER

0x0020

使用invokespecial语义

类和接口

ACC_INTERFACE

0x0200

接口类型,不是类类型

所有接口,没有类

ACC_ABSTRACT

0x0400

Abstract类型

所有接口,部分类

5. 类索引(this_class)
    this_class是一个对常量池的索引。在this_class位置的常量池入口必须为CONSTANT_Class_info表。该表由两个部分组成——tag和name_index。tag部分是一个具有CONSTANT_Class值的常量,name_index位置的常量池入口为一个包含了类或接口全限定名的CONSTANT_Utf8_info表。
6. 父类索引(super_class)
    super_class是一个两个字节的常量池索引。在super_class位置的常量池入口是一个指向该类超类全限定名的CONSTANT_Class_info入口。因为Java程序中所有对象的基类都是java.lang.Object类,除了Object类以外,常量池索引super_class对于所有的类均有效。对于Object类,super_class的值为0。对于接口,在常量池入口super_class位置的项为java.lang.Object。
7. 接口(Interfaces)
    interfaces_count表示在文件中由该类直接实现或者由接口所扩展的父接口的数量。在这个计数的后面,是名为interfaces的数组,它包含了对每个由该类或者接口直接实现的父接口的常量池索引。每个父接口都使用一个常量池中的CONSTANT_Class_info入口来描述,该CONSTANT_Class_info入口指向接口的全限定名。这个数组只容纳那些直接出现在类声明的implements子句或者接口声明的extends子句中的父接口。超类按照在implements子句和extends子句中出现的顺序(从左到右)在这个数组中显现。
8. 字段(Fields)
    fields_count表示类变量和实例变量的字段的数量总和。在这个计数后面的是不同长度的field_info表的序列(fields_count指出了序列中有多少个field_info表)。只有在文件中由类或者接口声明了的字段才能在fields列表中列出。在fields列表中,不列出从超类或者父接口继承而来的字段。另一方面,fields列表可能会包含在对应的Java源文件中没有叙述的字段,这是因为Java编译器可以会在编译时向类或者接口添加字段。
field_info表的格式如下所示:
类型
名称
说明
数量
U2
access_flags
字段访问权限
1
U2
name_index
字段名称
1
U2
descriptor_index
字段描述符
1
U2
attributes_count
attributes 项目数
1
attribute_info
attributes
attribute_info 列表
attributes_count
access_flags指定字段的访问修饰符,所使用的标志位如下表所示:

标准名称

设定含义

设定者

ACC_PUBLIC

0x0001

public

类和接口

ACC_PRIVATE

0x0002

private

只有类

ACC_PROTECTED

0x0004

protected

只有类

ACC_STATIC

0x0008

static

类和接口

ACC_FINAL

0x0010

final

类和接口

ACC_VOILATIE

0x0040

volatile

只有类

ACC_TRANSIENT

0x0080

transient

只有类

name_index提供字段名称的 CONSTANT_Utf8_info表的索引
descriptor_index  提供字段描述符的 CONSTANT_Utf8_info表的索引
attributes项由多个attribute_info表组成的 列表,可以有任意数量的属性
   9. 方法(Methods)
    methods_count表示该类或者接口中声明多的所有方法的数量总和,只包括该类或者接口中显式定义的方法,不包括超类或者父接口中继承来的方法。method_info表包含了与方法相关的信息,包括方法名和描述符(返回值类型和参数类型、顺序和数量)。
method_info表的格式如下所示:
类型
名称
说明
数量
U2
access_flags
方法访问权限
1
U2
name_index
方法名称
1
U2
descriptor_index
方法描述符
1
U2
attributes_count
attributes  项目数
1
attribute_info
attributes
attribute_info  列表
attributes_count
access_flags指定方法的访问修饰符,所使用的标志位如下表所示:

标准名称

设定含义

设定者

ACC_PUBLIC

0x0001

public

类和所有的接口方法

ACC_PRIVATE

0x0002

private

只有类

ACC_PROTECTED

0x0004

protected

只有类

ACC_STATIC

0x0008

static

只有类

ACC_FINAL

0x0010

final

只有类

ACC_SYNCHRONIZED

0x0020

synchronized

只有类

ACC_NATIVE

0x0100

native

只有类

ACC_ABSTRACT

0x0400

abstract

类和所有的接口方法

ACC_STRICT

0x0800

strictFP

类和接口的<clinit>方法

method_info表的其他项的含义给跟field_info表的差不多。
10. 属性(Attributes)
    Attributes给出了在该文件类或者接口所定义的属性的基本信息。属性部分由attributes_count开始,attributes_count是指出现在后续attributes列表的attribute_info表的数量总和。每个attribute_info的第一项是指向常量池中CONSTANT_Utf8_info表的索引,该表给出了属性的名称。
    属性出现在class文件的多处,不同地方用到的属性的种类也不同。Java虚拟机定义了9种属性,如下表所示:

名称

使用者

描述

Code

method_info

方法的字节码和其他数据

ConstantValue

field_info

Final变量的值

Deprecated

field_info, method_info

字段或方法被禁用指示符

Exceptions

method_info

方法抛出的可被检测的异常

InnerClasses

ClassFile

内部、外部类的列表

LineNumberTable

Code_attribute

方法的行号与字节码的映射

LocalVariableTable

Code_attribute

方法局部变量的描述

SourceFile

ClassFile

源文件名

Synthetic

field_info, method_info

编译器产生的字段或方法的指示符


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
为什么要学JVM1、一切JAVA代码都运行在JVM之上,只有深入理解虚拟机才能写出更强大的代码,解决更深层次的问题。2、JVM是迈向高级工程师、架构师的必备技能,也是高薪、高职位的不二选择。3、同时,JVM又是各大软件公司笔试、面试的重中之重,据统计,头部的30家互利网公司,均将JVM作为笔试面试的内容之一。4、JVM内容庞大、并且复杂难学,通过视频学习是最快速的学习手段。课程介绍本课程包含11个大章节,总计102课时,无论是笔试、面试,还是日常工作,可以让您游刃有余。第1章 基础入门,从JVM是什么开始讲起,理解JDK、JRE、JVM的关系,java的编译流程和执行流程,让您轻松入门。第2章 字节码文件,深入剖析字节码文件的全部组成结构,以及javap和jbe可视化反解析工具的使用。第3章 类的加载、解释、编译,本章节带你深入理解类加载器的分类、范围、双亲委托策略,自己手写类加载器,理解字节码解释器、即时编译器、混合模式、热点代码检测、分层编译等核心知识。第4章 内存模型,本章节涵盖JVM内存模型的全部内容,程序计数器、虚拟机栈、本地方法栈、方法区、永久代、元空间等全部内容。第5章 对象模型,本章节带你深入理解对象的创建过程、内存分配的方法、让你不再稀里糊涂。第6章 GC基础,本章节是垃圾回收的入门章节,带你了解GC回收的标准是什么,什么是可达性分析、安全点、安全区,四种引用类型的使用和区别等等。第7章 GC算法与收集器,本章节是垃圾回收的重点,掌握各种垃圾回收算法,分代收集策略,7种垃圾回收器的原理和使用,垃圾回收器的组合及分代收集等。第8章 GC日志详解,各种垃圾回收器的日志都是不同的,怎么样读懂各种垃圾回收日志就是本章节的内容。第9章 性能监控与故障排除,本章节实战学习jcmd、jmx、jconsul、jvisualvm、JMC、jps、jstatd、jmap、jstack、jinfo、jprofile、jhat总计12种性能监控和故障排查工具的使用。第10章 阿里巴巴Arthas在线诊断工具,这是一个特别小惊喜,教您怎样使用当前最火热的arthas调优工具,在线诊断各种JVM问题。第11章 故障排除,本章会使用实际案例讲解单点故障、高并发和垃圾回收导致的CPU过高的问题,怎样排查和解决它们。课程资料课程附带配套项目源码2个159页高清PDF理论篇课件1份89页高清PDF实战篇课件1份Unsafe源码PDF课件1份class_stats字段说明PDF文件1份jcmd Thread.print解析说明文件1份JProfiler内存工具说明文件1份字节码可视化解析工具1份GC日志可视化工具1份命令行工具cmder 1份学习方法理论篇部分推荐每天学习2课时,可以在公交地铁上用手机进行学习。实战篇部分推荐对照视频,使用配套源码,一边练习一遍学习。课程内容较多,不要一次性学太多,而是要循序渐进,坚持学习。      

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值