1+2在JVM中的处理过程是什么样的?

简介: 1+2在JVM中的处理过程是什么样的?

1+2在JVM中的处理过程是什么样的?

接上几篇文章,我们了解了JVM运行时数据区域模型,JVM中的常用操作指令编码。下面我们来通过简单的例子a+b看看整个处理过程是怎么样的。

资料:

1、源码

public class AddDemo {
    public static void main(String[] args) {
        int a = 1;
        int b = 2;
        int c = add(a, b);
        System.out.println("c=" + c);
    }
    /***
     * a+b
     * @param a
     * @param b
     * @return
     */
    public static int add(int a, int b) {
        return a + b;
    }
}
复制代码

2、Class文件

因为JVM能够读懂的是Java源码编译后的Class文件,所以我们要看Class文件。源码反编译后的文件如下:

Classfile /Users/zhangjian/works/workspace_home/docker-demo/target/classes/com/jianjang/docker/study/base/AddDemo.class
  Last modified 2022-10-22; size 987 bytes
  MD5 checksum 667fc2791a7668878bb530f04b32b4f2
  Compiled from "AddDemo.java"
public class com.jianjang.docker.study.base.AddDemo
  minor version: 0
  major version: 52
  flags: ACC_PUBLIC, ACC_SUPER
Constant pool:
   #1 = Methodref          #12.#33        // java/lang/Object."<init>":()V
   #2 = Methodref          #11.#34        // com/jianjang/docker/study/base/AddDemo.add:(II)I
   #3 = Fieldref           #35.#36        // java/lang/System.out:Ljava/io/PrintStream;
   #4 = Class              #37            // java/lang/StringBuilder
   #5 = Methodref          #4.#33         // java/lang/StringBuilder."<init>":()V
   #6 = String             #38            // c=
   #7 = Methodref          #4.#39         // java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
   #8 = Methodref          #4.#40         // java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
   #9 = Methodref          #4.#41         // java/lang/StringBuilder.toString:()Ljava/lang/String;
  #10 = Methodref          #42.#43        // java/io/PrintStream.println:(Ljava/lang/String;)V
  #11 = Class              #44            // com/jianjang/docker/study/base/AddDemo
  #12 = Class              #45            // java/lang/Object
  #13 = Utf8               <init>
  #14 = Utf8               ()V
  #15 = Utf8               Code
  #16 = Utf8               LineNumberTable
  #17 = Utf8               LocalVariableTable
  #18 = Utf8               this
  #19 = Utf8               Lcom/jianjang/docker/study/base/AddDemo;
  #20 = Utf8               main
  #21 = Utf8               ([Ljava/lang/String;)V
  #22 = Utf8               args
  #23 = Utf8               [Ljava/lang/String;
  #24 = Utf8               a
  #25 = Utf8               I
  #26 = Utf8               b
  #27 = Utf8               c
  #28 = Utf8               MethodParameters
  #29 = Utf8               add
  #30 = Utf8               (II)I
  #31 = Utf8               SourceFile
  #32 = Utf8               AddDemo.java
  #33 = NameAndType        #13:#14        // "<init>":()V
  #34 = NameAndType        #29:#30        // add:(II)I
  #35 = Class              #46            // java/lang/System
  #36 = NameAndType        #47:#48        // out:Ljava/io/PrintStream;
  #37 = Utf8               java/lang/StringBuilder
  #38 = Utf8               c=
  #39 = NameAndType        #49:#50        // append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
  #40 = NameAndType        #49:#51        // append:(I)Ljava/lang/StringBuilder;
  #41 = NameAndType        #52:#53        // toString:()Ljava/lang/String;
  #42 = Class              #54            // java/io/PrintStream
  #43 = NameAndType        #55:#56        // println:(Ljava/lang/String;)V
  #44 = Utf8               com/jianjang/docker/study/base/AddDemo
  #45 = Utf8               java/lang/Object
  #46 = Utf8               java/lang/System
  #47 = Utf8               out
  #48 = Utf8               Ljava/io/PrintStream;
  #49 = Utf8               append
  #50 = Utf8               (Ljava/lang/String;)Ljava/lang/StringBuilder;
  #51 = Utf8               (I)Ljava/lang/StringBuilder;
  #52 = Utf8               toString
  #53 = Utf8               ()Ljava/lang/String;
  #54 = Utf8               java/io/PrintStream
  #55 = Utf8               println
  #56 = Utf8               (Ljava/lang/String;)V
{
  public com.jianjang.docker.study.base.AddDemo();
    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 11: 0
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
            0       5     0  this   Lcom/jianjang/docker/study/base/AddDemo;
  public static void main(java.lang.String[]);
    descriptor: ([Ljava/lang/String;)V
    flags: ACC_PUBLIC, ACC_STATIC
    Code:
      stack=3, locals=4, args_size=1
         0: iconst_1
         1: istore_1
         2: iconst_2
         3: istore_2
         4: iload_1
         5: iload_2
         6: invokestatic  #2                  // Method add:(II)I
         9: istore_3
        10: getstatic     #3                  // Field java/lang/System.out:Ljava/io/PrintStream;
        13: new           #4                  // class java/lang/StringBuilder
        16: dup
        17: invokespecial #5                  // Method java/lang/StringBuilder."<init>":()V
        20: ldc           #6                  // String c=
        22: invokevirtual #7                  // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
        25: iload_3
        26: invokevirtual #8                  // Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
        29: invokevirtual #9                  // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
        32: invokevirtual #10                 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
        35: return
      LineNumberTable:
        line 13: 0
        line 14: 2
        line 15: 4
        line 16: 10
        line 17: 35
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
            0      36     0  args   [Ljava/lang/String;
            2      34     1     a   I
            4      32     2     b   I
           10      26     3     c   I
    MethodParameters:
      Name                           Flags
      args
  public static int add(int, int);
    descriptor: (II)I
    flags: ACC_PUBLIC, ACC_STATIC
    Code:
      stack=2, locals=2, args_size=2
         0: iload_0
         1: iload_1
         2: iadd
         3: ireturn
      LineNumberTable:
        line 26: 0
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
            0       4     0     a   I
            0       4     1     b   I
    MethodParameters:
      Name                           Flags
      a
      b
}
SourceFile: "AddDemo.java"
复制代码

3、执行过程解读

关键字节码如下

public static void main(java.lang.String[]);
    descriptor: ([Ljava/lang/String;)V
    flags: ACC_PUBLIC, ACC_STATIC
    Code:
      stack=3, locals=4, args_size=1
         0: iconst_1  //将常量1加载到操作数栈
         1: istore_1  //将1从操作数栈存储到局部变量表
         2: iconst_2  //将常量2加载到操作数栈
         3: istore_2  //将2从操作数栈存储到局部变量表
         4: iload_1  //将局部变量表的常量1压入操作数栈
         5: iload_2  //将局部变量表的常量2压入操作数栈
         6: invokestatic  #2                  // Method add:(II)I //执行add方法
         9: istore_3   //将3从操作栈存储到局部变量表
//add方法
public static int add(int, int);
    descriptor: (II)I
    flags: ACC_PUBLIC, ACC_STATIC
    Code:
      stack=2, locals=2, args_size=2
         0: iload_0  //将局部变量表的第1个常量压入操作数栈
         1: iload_1  //将局部变量表的第2个常量压入操作数栈
         2: iadd   // 将最近的两个常量相加,并将结果压入操作数栈
         3: ireturn  //将结果压入调用方的栈顶(main方法栈顶)
复制代码

示意图1-main栈帧

网络异常,图片无法展示
|

示意图2-add栈帧

网络异常,图片无法展示
|

至此,整个操作过程解析结束。个人理解,有问题的话,感谢联系改正。谢谢。

目录
相关文章
|
2月前
|
存储 Java Linux
【JVM】JVM执行流程和内存区域划分
【JVM】JVM执行流程和内存区域划分
54 1
|
7月前
|
存储 缓存 算法
深入浅出JVM(二)之运行时数据区和内存溢出异常
深入浅出JVM(二)之运行时数据区和内存溢出异常
|
4月前
|
存储 算法 Java
JVM组成结构详解:类加载、运行时数据区、执行引擎与垃圾收集器的协同工作
【8月更文挑战第25天】Java虚拟机(JVM)是Java平台的核心,它使Java程序能在任何支持JVM的平台上运行。JVM包含复杂的结构,如类加载子系统、运行时数据区、执行引擎、本地库接口和垃圾收集器。例如,当运行含有第三方库的程序时,类加载子系统会加载必要的.class文件;运行时数据区管理程序数据,如对象实例存储在堆中;执行引擎执行字节码;本地库接口允许Java调用本地应用程序;垃圾收集器则负责清理不再使用的对象,防止内存泄漏。这些组件协同工作,确保了Java程序的高效运行。
34 3
|
4月前
|
存储 监控 算法
深入解析JVM内部结构及GC机制的实战应用
深入解析JVM内部结构及GC机制的实战应用
|
7月前
|
算法 安全 Java
【JVM】并发的可达性分析详细解释
【JVM】并发的可达性分析详细解释
|
7月前
|
算法 Java 应用服务中间件
深入理解JVM - 阶段总结与回顾(一)
深入理解JVM - 阶段总结与回顾(一)
47 0
|
7月前
|
Java
JVM new一个对象过程
【1月更文挑战第4天】JVM new一个对象过程
|
存储 算法 安全
【jvm系列-10】深入理解jvm垃圾回收器的种类以及内部的执行原理
【jvm系列-10】深入理解jvm垃圾回收器的种类以及内部的执行原理
218 0
|
Java Spring
jvm类的加载过程
jvm类的加载过程
83 0
|
安全 Java 编译器
jvm类的加载机制
jvm类的加载机制
70 0

相关实验场景

更多