本文内容主要来源于《分布式java应用与基础实践》
JVM规范定义的标准结构如下图所示。

JVM负责装载class文件并执行,下面一系列文章将会说明JVM是怎样将java文件编译为class,如何装载class,如何执行class,以及JVM对上述过程做了哪些优化。
编译机制
javac将Java源码编译为class文件的步骤如下。

1.分析和输入到符号表
Parse过程主要做的是词法和语法分析。词法分析:将代码字符转化为token序列,语法分析:将token序列转化为抽象语法树。
Enter过程主要是将符号输入到符号表,包括确认类的超类型,接口,是否添加默认构造器。
2.注解处理
JDK5.0开始提供注解功能,这个步骤主要是处理用户自定义的注解来简化开发工作量。基本上常用的开源项目都会采用大量的注解,常见的比如:Hibernate
,Spring
。
3.语义分析和生成class文件
语义分析:主要是进行语法检查,泛型推导,泛型擦除,异常捕获,解除语法糖。完成语义分析后开始JVM开始根据抽象语法树生成class文件。class文件包含三类信息:
- 结构信息:class文件格式版本号及各部分的数量和大小。
- 元数据:类变量,方法声明和常量池。
- 方法信息:字节码,异常处理器表,求值栈和局部变量区大小,求值栈的类型记录,调试用符号信息。
javac -g D:\Demo.java
:
public class Demo {
private static final String name = "demo";
private int age = 2;
public Demo(int age) {
this.age = age;
}
public void print(int age) throws Exception {
int temp = 3;
System.out.println(age);
}
}
javap -l -v D:\Demo.class
:
Classfile /D:/Demo.class
Last modified 2017-5-9; size 762 bytes
MD5 checksum 4012566c34e8ecf5377d4e1a9bc1a872
Compiled from "Demo.java"
public class com.rjra.ha.home.thirdpart.web.controller.daoJia.requestParam.Demo
minor version: 0
major version: 52
flags: ACC_PUBLIC, ACC_SUPER
Constant pool:
#1 = Methodref #6.#26 // java/lang/Object."<init>":()V
#2 = Fieldref #5.#27 // com/rjra/ha/home/thirdpart/web/controller/daoJia/requestParam/Demo.age:I
#3 = Fieldref #28.#29 // java/lang/System.out:Ljava/io/PrintStream;
#4 = Methodref #30.#31 // java/io/PrintStream.println:(I)V
#5 = Class #32 // com/rjra/ha/home/thirdpart/web/controller/daoJia/requestParam/Demo
#6 = Class #33 // java/lang/Object
#7 = Utf8 name
#8 = Utf8 Ljava/lang/String;
#9 = Utf8 ConstantValue
#10 = String #34 // demo
#11 = Utf8 age
#12 = Utf8 I
#13 = Utf8 <init>
#14 = Utf8 (I)V
#15 = Utf8 Code
#16 = Utf8 LineNumberTable
#17 = Utf8 LocalVariableTable
#18 = Utf8 this
#19 = Utf8 Lcom/rjra/ha/home/thirdpart/web/controller/daoJia/requestParam/Demo;
#20 = Utf8 print
#21 = Utf8 temp
#22 = Utf8 Exceptions
#23 = Class #35 // java/lang/Exception
#24 = Utf8 SourceFile
#25 = Utf8 Demo.java
#26 = NameAndType #13:#36 // "<init>":()V
#27 = NameAndType #11:#12 // age:I
#28 = Class #37 // java/lang/System
#29 = NameAndType #38:#39 // out:Ljava/io/PrintStream;
#30 = Class #40 // java/io/PrintStream
#31 = NameAndType #41:#14 // println:(I)V
#32 = Utf8 com/rjra/ha/home/thirdpart/web/controller/daoJia/requestParam/Demo
#33 = Utf8 java/lang/Object
#34 = Utf8 demo
#35 = Utf8 java/lang/Exception
#36 = Utf8 ()V
#37 = Utf8 java/lang/System
#38 = Utf8 out
#39 = Utf8 Ljava/io/PrintStream;
#40 = Utf8 java/io/PrintStream
#41 = Utf8 println
{
public com.rjra.ha.home.thirdpart.web.controller.daoJia.requestParam.Demo(int);
descriptor: (I)V
flags: ACC_PUBLIC
Code:
stack=2, locals=2, args_size=2
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: aload_0
5: iconst_2
6: putfield #2 // Field age:I
9: aload_0
10: iload_1
11: putfield #2 // Field age:I
14: return
LineNumberTable:
line 7: 0
line 5: 4
line 8: 9
line 9: 14
LocalVariableTable:
Start Length Slot Name Signature
0 15 0 this Lcom/rjra/ha/home/thirdpart/web/controller/daoJia/requestParam/Demo;
0 15 1 age I
public void print(int) throws java.lang.Exception;
descriptor: (I)V
flags: ACC_PUBLIC
Code:
stack=2, locals=3, args_size=2
0: iconst_3
1: istore_2
2: getstatic #3 // Field java/lang/System.out:Ljava/io/PrintStream;
5: iload_1
6: invokevirtual #4 // Method java/io/PrintStream.println:(I)V
9: return
LineNumberTable:
line 12: 0
line 13: 2
line 14: 9
LocalVariableTable:
Start Length Slot Name Signature
0 10 0 this Lcom/rjra/ha/home/thirdpart/web/controller/daoJia/requestParam/Demo;
0 10 1 age I
2 8 2 temp I
Exceptions:
throws java.lang.Exception
}
SourceFile: "Demo.java"
网友评论