JVM - 编译机制

本文内容主要来源于《分布式java应用与基础实践》

JVM规范定义的标准结构如下图所示。

JVM - 编译机制_第1张图片
Paste_Image.png

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

编译机制

javac将Java源码编译为class文件的步骤如下。

Paste_Image.png

1.分析和输入到符号表

Parse过程主要做的是词法和语法分析。词法分析:将代码字符转化为token序列,语法分析:将token序列转化为抽象语法树。
Enter过程主要是将符号输入到符号表,包括确认类的超类型,接口,是否添加默认构造器。

2.注解处理

JDK5.0开始提供注解功能,这个步骤主要是处理用户自定义的注解来简化开发工作量。基本上常用的开源项目都会采用大量的注解,常见的比如:HibernateSpring

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."":()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               
  #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        // "":()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."":()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"

你可能感兴趣的:(JVM - 编译机制)