网站首页 > java教程 正文
Windows 操作系统上编译的 Java 程序,不经过修改就能够直接在 Linux 操作系统上运行;与之对比的是 C 语言,在 Linux 平台编译的 C 程序,一般情况下如果不进行特殊的转换,那么是不能在 Windows 操作系统上运行的。
要了解 Java 是如何实现这一目标的,我们需要对 Java实际的运行做一个简单的介绍。首先 Java 的源程序的扩展名是.java,经过编译程序编译之后生成扩展为.class 的字节码文件。
本文分析class文件的格式,描述 Java 如何执行字节码,并通过 ASM 工具动态生成属性访问工具类,它类似 ReflectASM,是一个高性能反射处理工具。
一、基础知识:
在.class 文件中,类名使用的都是全限定名,并且其表示方式与源文件中的方式不一致,比如 java.lang.String 在 String.class 中的表示方式就是 java/lang/String。
Java 虚拟机的操作基于两种数据类型:基本类型和引用类型。
1.基本类型:包括数字类型、boolean 类型和 returnAddress,其中 returnAddress 在 Java 语言中没有对应类型。
2.引用类型:包括 class、array、interface,引用类型是与实例关联的。这些类型在.class 文件中有不同的描述,如下表所示。
引用类型举例,如下表所示。
方法的描述是参数类型描述与返回类型描述的组合,参数类型描述在一对()之间,后边紧跟返回类型的描述。我们以 java.lang.Object 与 java.lang.String 中的几个方法举例,如下表所示。
二、.class文件的格式
.class 文件的格式(类似 C 语言)如下:
ClassFile {
u4 magic;
u2 minor_version;
u2 major_version;
u2 constant_pool_count;
cp_info constant_pool[constant_pool_count-1];
u2 access_flags;
u2 this_class;
u2 super_class;
u2 interfaces_count;
u2 interfaces[interfaces_count];
u2 fields_count;
field_info fields[fields_count];
u2 methods_count;
method_info methods[methods_count];
u2 attributes_count;
attribute_info attributes[attributes_count];
}
classFile 是二进制字节流,以 8 位二进制数据为基础构成,虽然可以区分一个个数据项,但其结构是按顺序线性排列的,各个数据项中间没有其他的分隔符。
在 class 文件的结构中,只有两种数据类型:无符号数和表。其中 u1、u2、u4 分别代表无符号 1 个字节、2 个字节、4 个字节,而且其多字节的排列是“大端法”,即高位字节在低位。 “表”是由多个无符号数或其他表项构成的,比如 cp_info 表示的就是常量池表。
1.Magic:魔数,4 个字节,固定为 0xCAFEBABE。
2.minor_version、major_version:分别占 2 个字节,表示子版本号和主版本号,用于 Java 虚拟机识别是否支持该.class 文件,以及是否支持新特性等。
3.constant_pool_count:2 个字节,其表示的值为常量池的实际大小+1。
4.constant_pool[]:常量池,其中包含各种格式的常量,包括类的全限定名、字段名称和描述符、方法名称和描述符等,其通用格式为 cp_info{u1 tag;u1 info[]},由于篇幅有限,不再详细展开介绍常量池结构。我们知道 Java 类的所有常量、类名、方法名等字符串都存放在常量池中。
5.access_flags:2 个字节,表示该类或接口的访问标志,比如 ACC_PUBLIC(值为 0x0001)表示 public,ACC_FINAL 表示 final(值为 0x0010),因此 0x0011 表示 final public。
6.this_class:2 个字节,表示当前类,其值为常量池中的索引,该位置所表示的常量类型必须为 0x07,即 class 类型。
7.super_class:2 个字节,表示当前类的直接父类,其值为常量池中的索引。该位置所表示的常量类型必须为 0x07,即 class 类型,当然在 Object 类的.class 文件中,该值为 0x0000。
8.interfaces_count:2 个字节,表示当前类或接口直接实现的接口的数量。
9.interfaces[]:表示直接实现的接口,其值为常量池中索引的位置,且类型必须为 0x07。
10.interfaces_count:2 个字节,表示当前类或接口直接实现的接口的数量。
11.interfaces[]:表示直接实现的接口,其值为常量池中索引的位置,且类型必须为 0x07。
12.methods_count:2 个字节,表示该类的方法表中方法结构的数量。
13.methods[]:方法表,表示该类中的所有方法,包括实例方法、类方法、初始化方法等,不包括从父类或父接口中继承但没实现的方法。
14.attributes_count:2 个字节,表示该.class 文件的属性表中实体的数量。
15.attributes[]:属性表,此位置的属性表示的是.class 文件中的属性,存储在此位置的属性是有限值的。
字段的结构如下:
field_info {
u2 access_flags;
u2 name_index;
u2 descriptor_index;
u2 attributes_count;
attribute_info attributes[attributes_count];
}
方法的结构如下:
method_info {
u2 access_flags;
u2 name_index;
u2 descriptor_index;
u2 attributes_count;
attribute_info attributes[attributes_count];
}
属性的结构如下:
attribute_info {
u2 attribute_name_index;
u4 attribute_length;
u1 info[attribute_length];
}
我们看到 Class、Filed、Method,甚至在 Attribute 中都有属性结构,但不同的位置拥有的属性是不同的,比如 SourceFile 属性存储在 ClassFile 中,Code 属性存储在 Method 结构中,而存储字节码对应 Java 源码行号的 LineNumberTable 和描述本地变量表中变量与 Java 源码变量对应关系的 LocalVariableTable 属性则存储在 Code 属性中,用于 Java Debug。
内容摘自《高性能Java系统权威指南》第九章
本书特点:
内容上,总结作者从事Java开发20年来在头部IT企业的高并发系统经历的真实案例,极具参考意义和可读性。
对于程序员和架构师而言,Java 系统的性能优化是一个超常规的挑战。这是因为 Java 语言和 Java 运行平台,以及 Java 生态的复杂性决定了 Java 系统的性能优化不再是简单的升级配置或者简单的 “空间换时间”的技术实现,这涉及 Java 的各种知识点。
本书从高性能、易维护、代码增强以及在微服务系统中编写Java代码的角度来描述如何实现高性能Java系统,结合真实案例,让读者能够快速上手实战。
风格上,本书的风格偏实战,读者可以下载书中的示例代码并运行测试。读者可以从任意一章开始阅读,掌握性能优化知识为公司的系统所用。
本书适合:
中高级程序员和架构师;
以及有志从事基础技术研发、开源工具研发的极客阅读;
也可以作为 Java 笔试和面试的参考书。
- 上一篇: JVM系列:几张图看懂java字节码
- 下一篇: Java字节码指令:dadd
猜你喜欢
- 2025-01-07 Python GUI 编程:tkinter 初学者入门指南——几何布局管理器 Place
- 2025-01-07 偷天换日,用JavaAgent欺骗你的JVM
- 2025-01-07 大数据必学Java基础(二):Java核心机制
- 2025-01-07 求你了,别再说 Java 对象都是在堆内存上分配空间了
- 2025-01-07 Java 虚拟机是什么?——探秘 JVM 的核心机制!
- 2025-01-07 5.2 JVM常见问题及面试题
- 2025-01-07 JVM实战—1.Java代码的运行原理
- 2025-01-07 浅谈字节码增强技术系列2-Asm与Cglib
- 2025-01-07 【JVM字节码】Class文件与字节码,机器码的关系
- 2025-01-07 虚拟机字节码操作黑科技工具简介
你 发表评论:
欢迎- 04-24Java Collections 工具类集合框架中常用算法解析
- 04-24桶排序的简单理解
- 04-24Java集合框架底层实现原理大揭秘
- 04-24Java 集合框架全面解析:选对数据结构,提升开发效率
- 04-24c#集合排序
- 04-24Java面试中常被问到的集合类深度解读
- 04-24VBA技术资料MF278:对集合进行排序
- 04-24Spring 最常用的 7 大类注解,史上最强整理
- 最近发表
- 标签列表
-
- java反编译工具 (77)
- java反射 (57)
- java接口 (61)
- java随机数 (63)
- java7下载 (59)
- java数据结构 (61)
- java 三目运算符 (65)
- java对象转map (63)
- Java继承 (69)
- java字符串替换 (60)
- 快速排序java (59)
- java并发编程 (58)
- java api文档 (60)
- centos安装java (57)
- java调用webservice接口 (61)
- java深拷贝 (61)
- 工厂模式java (59)
- java代理模式 (59)
- java.lang (57)
- java连接mysql数据库 (67)
- java重载 (68)
- java 循环语句 (66)
- java反序列化 (58)
- java时间函数 (60)
- java是值传递还是引用传递 (62)
本文暂时没有评论,来添加一个吧(●'◡'●)