- 浏览: 374648 次
- 性别:
- 来自: 杭州
文章分类
最新评论
-
surpassno:
很不错,学习了
一个对象占用多少字节? -
ysyzww:
你这么牛逼,你父母知道吗
maven使用技巧 -
妖人不要跑:
JDK中反序列化对象的过程(ObjectInputStream#readObject) -
lanhz:
谢楼主,构建成功了
Mac OSX 10.9 上build openjdk8和openjdk7 -
zqb666kkk:
通过了吗 ?????
淘宝北京专场java面试题(2011-12-31)
一、概述
Java的源码编译后的class文件,具有非常严谨的结构,文件各个部分内容的完整性也通过自身描述来校验。
开始描述class文件内容前,我们先定义一些说明:u1代表一个字节,也是两个16进制字符,u2、u4、u8分别代表2、4、8个字节
二、类文件整体结构
名称 | 类型*长度 | 字段含义 |
魔数 | u4 * 1 | 固定值,十六进制表示是CAFEBABE,表示该文件是一个class文件,装载类文件的时候就会校验前四个字节是不是该魔数 |
minor version | u2 * 1 | 次版本号 |
major version | u2 * 1 |
主版本号,jvm在加载class文件后,会判断当前虚拟机版本是否可以处理此class文件,jvm只能处理某个版本以下版本的class文件,因为高版本的class文件可能会新加了很多特性,老的vm是识别不了的。此处某版本的计算方式是,对于1.X版本的虚拟机,只能处理major版本号<= 44+X的class文件。如1.5的vm只能处理49及以下的class文件 |
constant_pool_count | u2 * 1 | 常量池entry(入口、条)的数目 |
constant_pool | cp_info * (constant pool count-1) | 常量池存储的字面量literal、整数、浮点数、类名、方法名、类描述符、方法描述符、字段名、字段描述符等 |
access_flag |
u2 * 1 |
该类/接口的访问标示,一共有ACC_FINAL、ACC_PUBLIC、ACC_ABSTRACT、ACC_INTERFACE、ACC_SUPER、ACC_SYNTHETIC、ACC_ANNOTATION、ACC_ENUM 8种类型 |
this_class |
u2 * 1 |
当前类型信息,指向常量池中类型为Class的entry |
super_class |
u2 * 1 |
超类信息,指向常量池中类型为Class的entry |
interface_count | u2 * 1 | 实现的接口的数目 |
interfaces | u2 * interface_count | 实现的接口信息,每一项都指向常量池中的类型为Class的entry |
field_count |
u2 * 1 |
该类/接口中字段个数 |
fields | field_info * field_count | 字段信息,每一项都是一个field_info结构 |
method_count | u2 * 1 | 方法数量 |
methods | method _info * method_count | 方法数量,每一项都是一个method_info结构 |
attribute_count | u2 * 1 | 属性的个数 |
attributes | attribute_info * attribute_count | 属性,每一项都是一个attribute_info结构 |
二、常量池
常量池共有12中类型:Constant_Utf8_info、Constant_Integer_info、Constant_Float_info、Constant_Long_info、Constant_Double_info、Constant_String_info、Constant_Class_info、Constant_Fieldref_info、Constant_Methodref_info、Constant_InterfaceMethodref_info、Constant_NameAndType_info。每种常量info都是如下格式:
名称 | 类型 * 数量 | 含义 |
tag | u1 * 1 | 用来标示类型,不同类型的tag值不同 |
info | info * 1 | 根据不同的tag,info信息不同 |
1、Constant_Utf8_info,表示字面量
名称 | 类型 * 数量 | 含义 |
tag | u1 * 1 | 取值1 |
length | u1 * 1 | 字面量值的长度 |
bytes | u1 * length | 字面量值 |
2、Constant_Integer_info,表示整型值
名称 | 类型 * 数量 | 含义 |
tag | u1 * 1 | 取值3 |
length | u4 * 1 | integer的值 |
3、Constant_Float_info,表示单精度浮点类型
名称 | 类型 * 数量 | 含义 |
tag | u1 * 1 | 取值4 |
length | u4 * 1 | float的值 |
4、Constant_Long_info,表示long值
名称 | 类型 * 数量 | 含义 |
tag | u1 * 1 | 取值5 |
length | u8 * 1 | long值 |
5、Constant_Double_info,表示双精度浮点型值
名称 | 类型 * 数量 | 含义 |
tag | u1 * 1 | 取值6 |
length | u4 * 1 | double值 |
6、Constant_Class_info,表示类型信息
名称 | 类型 * 数量 | 含义 |
tag | u1 * 1 | 取值7 |
name_index | u2 * 1 | 指向全限定名的索引,全限定名存储在Constant_Utf8_info中 |
7、Constant_String_info,表示字符串
名称 | 类型 * 数量 | 含义 |
tag | u1 * 1 | 取值8 |
string_index | u2 * 1 | 指向字符串字面量(Constant_Utf8_info)的索引 |
8、Constant_Fieldref_info,表示引用到的别的类的字段信息,注意是引用到的,不是自己类的
名称 | 类型 * 数量 | 含义 |
tag | u1 * 1 | 取值9 |
class_index | u2 * 1 | 字段所属的类,指向Constant_Class_info的索引 |
name_and_type_index | u2 * 1 | 方法描述符,指向Constant_NameAndType_info的索引 |
9、Constant_Methodref_info,表示引用到的方法信息
名称 | 类型 * 数量 | 含义 |
tag | u1 * 1 | 取值10 |
class_index | u2 * 1 | 方法所属的类,指向Constant_Class_info的索引 |
name_and_type_index | u2 * 1 | 方法描述符,指向Constant_NameAndType_info的索引 |
10、Constant_InterfaceMethodref_info,表示引用到的接口方法信息
名称 | 类型 * 数量 | 含义 |
tag | u1 * 1 | 取值11 |
interface_index | u2 * 1 | 方法所属的接口,指向Constant_Class_info的索引 |
name_and_type_index | u2 * 1 | 方法描述符,指向Constant_NameAndType_info的索引 |
11、Constant_NameAndType_info,表示字段或方法的描述符信息,包括名称和描述
名称 | 类型 * 数量 | 含义 |
tag | u1 * 1 | 取值12 |
name_index | u2 * 1 | 方法、字段的名称,指向Constant_Utf8_info的索引 |
descriptor_index | u2 * 1 | 方法、字段的描述符,如([I,[java\lang\String) v 指向Constant_Utf8_info的索引 |
三、字段,当前类/接口的字段信息
名称 | 类型 * 数量 | 含义 |
access_flag | u2 * 1 | 访问标示,ACC_PRIVATE、 ACC_PROTECTED、 ACC_PUBLIC、 ACC_FINAL、 ACC_STATIC、 ACC_SYNTHETIC、 ACC_VOLATILE、 ACC_TRANSIENT、ACC_ENUM |
name_index | u2 * 1 | 字段名称,指向常量池Constant_Utf8_info的索引 |
descriptor_index | u2 * 1 | 描述符信息,指向常量池Constant_Utf8_info的索引,取值B、 C、 D、 F、 I、 J、 S、 Z、 V、 L |
attribute_count | u2 * 1 | 属性数量 |
attributes | attribute_info * attribute_count | 属性信息,可以有ConstantValue、Synthetic、Deprecated、Signature、RuntimeVisibleAnnotations、RuntimeInvisibleAnnotations |
四、方法,当前类/接口的方法信息
名称 | 类型 * 数量 | 含义 |
access_flag | u2 * 1 | 访问标示,ACC_PRIVATE、 ACC_PROTECTED、 ACC_PUBLIC、 ACC_FINAL、 ACC_STATIC、 ACC_SYNTHETIC、 ACC_ABSTRACT、 ACC_SYNCHRONIZED、ACC_VARARGS、 ACC_NATIVE、 ACC_STRICT、 ACC_BRIDGE |
name_index | u2 * 1 | 字段名称,指向常量池Constant_Utf8_info的索引 |
descriptor_index | u2 * 1 | 描述符信息,指向常量池Constant_Utf8_info的索引,取值B、 C、 D、 F、 I、 J、 S、 Z、 V、 L |
attribute_count | u2 * 1 | 属性数量 |
attributes | attribute_info * attribute_count | 属性信息,可以有Synthetic、Deprecated、Code、Signature、RuntimeVisibleAnnotations、 RuntimeVisibleParameterAnnotation、 RuntimeInvisibleAnnotations、RuntimeInvisibleParameterAnnotation、Exceptions、AnnotationDefault |
五、属性,此处属性包括类属性和方法、字段属性
名称 | 类型 * 数量 | 含义 |
name_index | u2 * 1 | 属性名称,指向常量池Constant_Utf8_info的索引 |
attribute_length | u2 * 1 | 属性长度,用来控制后续访问字节的数量 |
info | info * 1 | 属性信息,不同的attribute信息不同 |
类的attribute有SourceFile存储源码文件信息-g:none/-g:source关开、InnerClass内部类信息、Deprecated、Synthetic、EnclosingMethod局部类匿名类的访问范围、Signature泛型特征签名、SourceDebugExtension额外调试信息如jsp调试、RuntimeVisibleAnnotations运行时可见的Annotation、RuntimeInvisibleAnnotations运行时不可见的Annotation、LocalVariableTypeTable使用特征签名代替描述符
另外还有一些描述Attribute本身的attribute,比如Code就包含有LineNumberTable、LocalVariableTable
此处不详细列出attribute
发表评论
-
一次Direct buffer memory引发的OutOfMemoryError问题排查
2014-10-28 17:22 0留坑位 -
jvm运行期打印汇编信息
2014-04-09 23:00 3148如果只在jvm参数中加入-XX:+Prin ... -
Mac OSX 10.9 上build openjdk8和openjdk7
2014-03-29 18:29 14276先分享下自己build出来的fastdeb ... -
内存充足情况下应用一直CMS GC的问题分析
2014-03-26 22:39 0前几天日常上线发布后,收到大量的CMS GC ... -
查看java对象在内存中的布局
2014-03-20 22:39 13060接着上篇《一个对象占用多少字节?》中遇到的 ... -
一个对象占用多少字节?
2014-03-18 21:56 35100老早之前写过一篇博客,是关于一个Integ ... -
cpu字长、操作系统字长和jvm中各数据类型占用的字节数关系
2014-03-16 02:05 4710cpu字长是指cpu同时参与运算的二进制位 ... -
cache line对内存访问的影响
2014-03-12 20:48 1374cache line对内存访问的影响很早就 ... -
一次线上问题的排查过程——时钟精度变化导致的cpu占用率高的问题
2013-09-16 21:14 4166最近升级了一次tair(缓存系统)的cli ... -
Kilim源码分析之五 ---- 织入之变量活跃性分析
2013-03-20 21:00 1212/** * In live va ... -
Kilim源码分析之四 ---- 织入之内联subroutine
2013-03-20 20:00 1492小于1.5编译级别时,如果不显示inlin ... -
Kilim源码分析之三 ---- 织入之构造/合并BasicBlock
2013-03-20 19:50 1431上一篇分析 ... -
在编译级别1.4时jvm编译try/catch/finally块的方式
2013-03-12 21:22 1472先上一段很简单,且不考虑健壮性的源码: ... -
ASM4.0源码走读之三 readCode方法分析方法代码
2013-03-09 00:19 1776继第一篇,我们来看看readCode的代码 ... -
ASM4.0源码走读之二 指令的类型
2013-03-08 23:51 1687在深入分析ClassReader.read ... -
ASM4.0源码走读之一
2013-03-08 23:18 1814了解java class ... -
java协程框架----kilim实现机制解析
2013-03-08 16:14 6624java语言处理多任务的模式是基于多线程,java语言级 ... -
Kilim源码分析之二 ---- 织入入口及可织入判断
2013-03-20 19:33 31211、织入入口,配置 1.1、织入入口 ... -
由一个小程序引发的思考 — 关于字段和方法的分派
2011-11-05 14:32 1840面向对象三大特征封装 ... -
JVM学习笔记十四 之 线程模型和锁
2011-10-24 02:30 0os线程模型、jvm线程、java线程调度、状态 线程安全程 ...
相关推荐
本篇JVM学习笔记主要涵盖了以下几个核心知识点: 1. **运行时数据区**: - **程序计数器**:记录当前线程执行的字节码的行号,用于线程恢复执行时跳转到正确位置。 - **Java虚拟机栈**:每个方法执行时创建的栈帧...
### JVM学习笔记(一) #### 一、JVM概述与工具使用 JVM(Java Virtual Machine)是Java语言的核心组成部分之一,它为Java程序提供了一个跨平台的运行环境。本篇学习笔记主要介绍如何利用一系列工具来查看和监控JVM...
这个“java之jvm学习笔记五(实践写自己的类装载器)”很可能是对这一主题的详细探讨。 类装载器在Java中的主要职责是动态加载类到JVM中。Java的类装载器分为三个基本层次:启动类装载器(Bootstrap ClassLoader)、...
源码编译由Java源码编译器完成,这个过程包括了源码的分析、输入到符号表、注解处理和语义分析,最终生成包含结构信息、元数据和方法信息的.class文件。执行阶段则是由JVM执行引擎解析字节码并执行。这一过程涉及到...
【Java分布式应用学习笔记-谈JVM】 在Java分布式应用中,JVM(Java虚拟机)扮演着至关重要的角色。虽然有些人可能认为分布式系统与JVM的关系并不密切,但事实上,尤其是在大型分布式环境,如云计算服务平台,对Java...
- Java 虚拟机 (JVM) 不仅限于 Java 语言,而是与 "Class 文件" 这种特定的二进制文件格式绑定。这意味着任何可以编译成符合 JVM 规范的 Class 文件的语言都可以在 JVM 上运行。 - 统一且强大的 Class 文件结构是 ...
### JVM学习笔记 #### JVM内存模型 (JMM) JVM内存模型主要分为以下几个部分: - **Java堆**:这是所有线程共享的一块区域,在虚拟机启动时创建。主要用于存放对象实例,几乎所有的对象实例都在这里分配内存。 - *...
其中,加载是找到类的.class文件并读入内存;验证确保字节码的正确性;准备为类的静态变量分配内存并初始化为默认值;解析将符号引用转换为直接引用;初始化执行类的初始化方法。了解这个过程有助于我们理解和控制类...
加载是找到.class文件并读入内存;验证确保字节码的正确性,防止恶意代码;准备阶段为静态变量分配内存,并设置默认初始值;解析将符号引用转换为直接引用;初始化执行类构造器。 二、内存管理 JVM内存主要分为堆...
《JVM学习笔记》 Java虚拟机(JVM)是Java平台的核心组成部分,它负责运行所有的Java应用程序。这篇笔记将深入探讨JVM的工作原理、内存管理、类加载机制以及优化策略,帮助读者全面理解JVM并提升Java程序的性能。 ...
而C/C++语言将代码编译成01码,不同的操作系统的01码指令不同,这造成了不能跨平台,而Java将这个任务交给JVM,不同操作系统上的JVM将.class文件编译成不同的二进制码。 9.java se development 8uN ,其中N是JDK更新...
### JAVA学习笔记知识点详解 #### 一、计算机概述 1. **计算机**:电子设备,用于处理信息。 2. **计算机硬件**: - **中央处理器(CPU)**:计算机的大脑,负责处理指令。 - **内存(RAM)**:临时存储数据,...
### JVM学习笔记核心知识点整理 #### 一、引言与背景 随着软件开发技术的不断发展,Java作为一种广泛应用的编程语言,其背后的核心技术——Java虚拟机(JVM)的重要性日益凸显。掌握JVM不仅可以帮助开发者更好地理解...
- 编译:使用javac命令将源文件编译成字节码文件(.class)。 - 运行:使用java命令运行编译后的字节码文件。 3. **Eclipse IDE**: Eclipse是一个强大的Java集成开发环境,提供了一整套工具来帮助开发者编写、...
在每个`.class`文件的开头都有一个魔数(Magic Number),其值为`0xCAFEBABE`,用来识别文件格式。紧接着是`minor_version`和`major_version`字段,它们分别表示次版本号和主版本号,用于标识字节码对应的Java版本。...
【Java学习笔记】 Java是一种广泛使用的面向对象的编程语言,其设计目标是具有高效率、可移植性和可读性。本笔记将围绕Java的历史、重要性、安装配置、语法基础等方面进行详细介绍。 ### 1. Java的发展与意义 ...
这篇学习笔记主要探讨了Class文件的结构、内容和重要特性。 首先,Class文件是一种语言独立的存储格式,不仅用于Java,也可以支持其他如Scala等JVM为基础的语言。它由字节码构成,这种格式允许JVM执行不同语言编译...
这篇文档是个人的Java学习笔记总结,旨在帮助0基础的学习者从零开始掌握Java基础知识,并逐步成为专业的Java开发者。以下是笔记中涉及的一些关键知识点: 1. **Java开发环境的设置**: 要开始Java编程,首先需要...