一、JVM简介
JVM:Java Virtual MAchine-Java虚拟机,可以将class文件解释为各种平台可执行的指令行,java中一个类在运行时,首先将java文件编译(javac)为class文件,然后jvm将class文件解释并执行。
JVM可分为三部分:类加载器(ClassLoader)系统、执行引擎、运行时数据区。
类加载器系统:负责加载程序中的类和接口。
执行引擎:解释执行+即时编译(JIT),开始对所有的代码都采取解释执行的方式,经常调用的热点方法编译为本地代码(热点代码频率设置-XX:CompileThreshould = 值(默认10000)),默认是解释执行+即时编译(-Xmixed)模式,可设置为纯解释(-Xint)或者纯编译(-Xcomp)模式,纯解释加载快,执行慢,纯编译加载慢,执行快。
运行时数据区:程序计数器、本地方法栈、虚拟机栈、堆、方法区。
1.程序计数器:指向当前线程所执行的字节码的行号,线程私有。
2.本地方法栈:存储本地方法调用的状态,Native方法,线程私有。
3.虚拟机栈:存储局部变量表,操作数栈,动态链接,方法出口等信息,线程私有。
4.堆:虚拟机启动时创建,存放对象实例和数组,GC工作区域,线程共享。
5.方法区(metaspace):存储类的信息,如常量(final)、静态变量(static)、JIT(即时编译器)编译后的代码、运行时常量池、方法表(即存储一些不会变更的数据),GC工作区域(1.8及以后),线程共享。
6.直接内存:JDK1.4后增加,支持IO直接访问内核空间内存,取消从内核空间将数据拷贝到JVM内存过程。
JVM支持语言:JVM不光支持java语言,只要是能编译成class文件,并且符合class规范,JVM都支持,例如:Kotlin、Groovy、JRuby、Jython、Scala等,可以理解成跨语言的class文件解释执行平台。
二、class文件解析
1.class文件:就是二进制文件。
一个.java文件:
package com.company.jvm;
public class ClassShow {
}
编译后的class文件,用idea看:
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//
package com.company.jvm;
public class ClassShow {
//编译后会默认添加一个构造方法
public ClassShow() {
}
}
借助BinEd插件看class文件:
就是个二进制字节码文件。
2.class文件结构
二进制字节码文件JVM是能识别的,我们可以借助工具来查看,编译过后的class文件结构。
插件:jclasslib。
通过上图,一个class文件总共可以分六类:
1.General Infomation:通用信息。存储java版本号、常量池数量、类修饰符、当前类、父类、实现接口数量、属性数量、方法数量、附加属性数量。
2.Constant pool:常量池。存储常量、修饰符、方法名称、字段名称、基本数据类型值、类和接口的名成。
3.interfaces:存储实现的接口索引。
4.Fields:存储属性的信息。名称、类型、修饰符等。
5.Methods:存储方法的入参、返回值、名称、修饰符、方法如何实现(java的汇编语言)。
6.Attrbutes:类文件名称(SourceFile)、内部类列表(InnerClasses)、方法的字节码指令(Code)、方法抛出异常(Exceptions)、方法源码位置字节码指令的对应关系(LineNumberTale)、方法的局部变量描述(LocalVariableTable),final关键字定义的常量值(ConstantValue)。