前言:
而今小伙伴们对“java项目执行”可能比较讲究,我们都需要学习一些“java项目执行”的相关资讯。那么小编在网摘上收集了一些对于“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 笔试和面试的参考书。
标签: #java项目执行