JVM如何实现平台无关性和语言无关性的?
平台无关性:使用java编译器为java源码为统一存储格式的字节码文件,实现不同平台的JVM去解释执行字节码。
语言无关性:实现不同语言的编译器,编译成统一存储格式的字节码文件,由某平台JVM去解释执行字节码。
什么是高位在前?
就是各个字节上的各个bit代表的数据的数位是从高到低。
123,表示一百二十三,就是高位在前的大端数;如果表示三百二十一,就是高位在尾的小端数。
对class文件数据结构表的理解。
类似于C语言结构体,仍旧由无符号数组成,用于描述有层次关系的复合结构的数据。
field_info {
u2 access_flags;
u2 name_index;
u2 descriptor_index;
u2 attributes_count;
attribute_info attributes[attributes_count];
}
利用class文件数据结构如何表示某一类型数据的集合?
通常是一个前置的容器计数器n + n个连续的数据项组成。
如字段集合由1个u2类型的field_count和field_count个field_info数据项组成。
查看class文件的版本号。
方法一:用十六进制工具查看class文件,第7、8个字节即为版本号。
Linux工具:
od -t x1 Test.class 内核命令,推荐
hexdump Test.class
Windows工具:
Winhex16 还需要额外装个软件
文本编辑器的hexdump插件 如notepad++,vscode,推荐‘
方法二:使用反编译工具
javap -version Test.class
字节码查看器:
jclasslib bytecode viewer 用于查看字节码格式,神器呀
bytecode-viewer 一个java8 jar和android apk反向工程套件
由低版本JDK执行高版本class文件引发的异常。
Exception in thread "main" java.lang.UnsupportedClassVersionError: WriteLog : Unsupported major.minor version 52.0
52.0对应jdk1.8即class文件是由jdk1.8的编译器生成,而JVM的版本低于1.8时,报不支持的Class版本错误
理解常量池。
常量池中的常量并不是指java中被static final修饰的变量,而是整个字节码文件的一个共享资源仓库,方便被后面的数据项重用。分成两大类:字面量和符号引用。
字面量:基本类型字面量:当基本类型被static final修饰时生成,byte、char、boolean被转换成int
private final static int = 2;
字符串字面量:java中在任何地方出现的字符串字面量都被生成1个CONSTANT_String_info和1个CONSTANT_Utf8_info类型。
private String str = "hello";
utf-8字面量:
字节码文件中所有需要用到字符串描述的地方都会生成CONSTANT_Utf8_info类型。
符号引用:用来准确描述类、字段和方法的字符串。
描述类和接口:类和接口的全限定名 com/tiro/jvm/Test
描述字段: 类全限定义称.字符名称:字段描述符 com/tiro/jvm/Test.m:I
描述方法: 类全限定名称.方法名:方法描述符 java.lang.Object."<init>":()V
为什么常量池的常量数量比容器计数要少1个?
常量的索引从1开始,如果有21个常量,索引从1~20
第0项常量空出来用于某些指向常量池的索引值的数据在特定情况下需要表达“不引用任何一个常量池项目”的含义。
解读一个空类的class文件。
一个空类的class文件大小为182字节,也是一个合法的java字节码文件的最小存储空间了。
javap -verbose Test.class
常量池解读:
#1 = Methodref #3.#10 // java/lang/Object."<init>":()V //描述父类默认构造方法的符号引用
#2 = Class #11 // com/tiro/jvm/Test //描述当前类的符号引用
#3 = Class #12 // java/lang/Object //描述父类的符号引用
#4 = Utf8 <init> //默认构造方法的名称
#5 = Utf8 ()V //默认构造方法的描述符
#6 = Utf8 Code //方法的Code属性名称,所有方法都有
#7 = Utf8 LineNumberTable //方法的LineNumberTable属性名称,所有方法都有
#8 = Utf8 SourceFile //当前类的SourceFile属性名称
#9 = Utf8 Test.java //当前类的SourceFile属性值
#10 = NameAndType #4:#5 // "<init>":()V //默认构造方法的部分符号引用
#11 = Utf8 com/tiro/jvm/Test //当前类的全限定名称
#12 = Utf8 java/lang/Object //父类的全限定名称
方法解读:
当类没有显式定义构造方法时,会自动生成一个不带参数的构造方法。是不是很熟悉呀!
{
public com.tiro.jvm.Test();
descriptor: ()V
flags: ACC_PUBLIC
Code:
stack=1, locals=1, args_size=1
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: return
LineNumberTable:
line 3: 0
}
Code属性数据项的结构自行查阅。
stack=1,代表方法运行时,操作数栈深度的最大值。
locals=1,代表方法运行时,局部变量表的最大存储空间,单位为Slot。32位虚拟机中,不超过32位的数据类型占用1个Slot,long和double占用两个Slot;64位虚拟机中,所有的数据类型占用1个Slot。
args_size=1,代表当前的参数个数,隐含参数this必有,通常是存储在局部变量表的第0个Slot。
接着就是4条执行指令:
0: aload_0 把第0个Slot的引用(即this)加载到操作数栈;
1: invokespecial #1 调用父类java.lang.Object的默认构造方法,这条指令占3个字节,后两个字节存放操作数的常量索引
4: return 退出方法执行
解读实例变量、类变量、类常量的赋值。(以基础数据类型为例)
类常量:
public class Test {
private final static int m = 2;
public int add(int n) {
return m + n;
}
}
编译阶段:
在常量池中生成1个CONSTANT_Integer_info类型的常量;
与任何其它字面量和常量的运算立即进行;
在字段表中生成1个ConstantValue的属性,属性值指向常量池中的索引。
类加载阶段:
在加载阶段会把class文件常量池的内容放入方法区的运行时常量池时中(字符串常量被移到堆中了)
方法调用:
iconst_2 对于int类型,在编译时被直接写入指令的操作数中,不需要从运行时常量池中获取
ldc2_w #2 对于long、double类型,从运行时常量池中加载常量到操作数
类变量:
public class Test {
private static int m = 2;
public int add(int n) {
return m + n;
}
}
编译阶段:
如果类中有static语句块和类变量赋值行为,就会生成类初始化方法<clinit>,而类变量赋值在<clinit>中进行。
类加载阶段:
在准备阶段在方法区静态域中为类变量分配内存,为类变量赋零值,而不是实际值;
在初始化阶段执行<clinit>方法为类变量赋值。
方法调用:
getstatic #2 调用getstatic指令从方法区静态域中获取值
实例变量:
public class Test {
private int m = 2;
public int add(int n) {
return m + n;
}
}
对象初始化阶段:
创建对象时,会为每个对象在堆中分配该对象的内存空间,并把所有实例变量设置为零值。
调用对象的<init>方法时,为有初始值的实例变量赋值,用到了iconst_2和putfield #2两个指令。
相关推荐
深入理解jvm-2Edition-类文件结构(csdn)————程序
jvm源码解读以及jvm调优,看的过程中会把c-c++文件也会放到里面进行解读-jvm-original
JVM图解-JVM指令-JVM原型图.rar
nginx-upstream-jvm-route 支持nginx版本1.15 解决nginx: [emerg] invalid parameter "srun_id=tomcat1" 问题
JVM实战-JVM类加载机制案例分析
bcprov-ext-jdk15on-1.54.jar、bcprov-jdk15on-1.54.jar和ssl-provider-jvm16-0.2.jar附件下载
赠送Maven依赖信息文件:metrics-jvm-3.1.5.pom; 包含翻译后的API文档:metrics-jvm-3.1.5-javadoc-API文档-中文(简体)版.zip; Maven坐标:io.dropwizard.metrics:metrics-jvm:3.1.5; 标签:jvm、metrics、...
Moonbox(月光宝盒)是JVM-Sandbox生态下的,基于jvm-sandbox-repeater重新开发的一款流量回放平台产品。在jvm-sandbox-repeater基础上提供了更加丰富功能,同时便于线上部署和使用,更多对比参考。 使用场景 你...
此资源有两个文件,含 nginx-upstream-jvm-route 和 nginx 对应版本,都是tar.gz文件。 安装方法网上很多就不写了,亲测可用。 不用担心版本不匹配造成安装失败,再浪费积分去到处下载尝试的烦恼。 此资源有两个文件...
赠送Maven依赖信息文件:metrics-jvm-3.1.5.pom; 包含翻译后的API文档:metrics-jvm-3.1.5-javadoc-API文档-中文(简体)-英语-对照版.zip; Maven坐标:io.dropwizard.metrics:metrics-jvm:3.1.5; 标签:jvm、...
java jvm 参数 -Xms -Xmx -Xmn -Xss -
1、java虚拟机的基本介绍。 2、字节码的执行 3、常用的jvm参数配置 4、算法和种类 5、gc参数配置 6、类加载器 7、性能监控工具 8、jvm堆栈分析
JVM基础-超清文字版.pdf 这个是带完整目录书签的文字版本,文本内容可以复制的哦
JVM规范--高手总结 Java相关 1 1.1Java定义 1 1.2Java的开发流程 1 1.3Java运行的原理 2 1.4半编译半解释 3 1.5平台无关性 4 JVM内存模型 4 2.1 JVM规范 5 2.2 Sun JVM 8 2.3 SUN JVM内存管理(优化) 10 2.4 SUN JVM...
kotlinx-coroutines-io-jvm-0.1.1.jar
jvm-full-gc调优-jvm-full-gc
jvm调优-jvm
Jvm性能优化-JVM内存结构原理分析03
JVM的指令由一个字节长度、代表着某种特定操作含义的数字(成为操作码)以及跟随其后的零至多个代表此操作所需参数(操作数)而构成。JVM采用面向操作数栈而不是寄存器架构,所以大多只有一个操作码。
JVM 的运行机制 多线程 JVM 的内存区域 JVM 会创建操作系统的接口创建一个原生线程。JVM 线程和操作系统线程是一一对应的