方法区使用举例

一 代码

public class MethodAreaDemo {
    public static void main(String args[]) {
        int x = 500;
        int y = 100;
        int a = x / y;
        int b = 50;
        System.out.println(a+b);
    }
}

二 对应常量池

#1 = Methodref          #5.#24         // java/lang/Object."<init>":()V
#2 = Fieldref           #25.#26        // java/lang/System.out:Ljava/io/PrintStream;
#3 = Methodref          #27.#28        // java/io/PrintStream.println:(I)V
#4 = Class              #29            // com/atguigu/java1/MethodAreaDemo
#5 = Class              #30            // java/lang/Object
#6 = Utf8               <init>
#7 = Utf8               ()V
#8 = Utf8               Code
#9 = Utf8               LineNumberTable
#10 = Utf8               LocalVariableTable
#11 = Utf8               this
#12 = Utf8               Lcom/atguigu/java1/MethodAreaDemo;
#13 = Utf8               main
#14 = Utf8               ([Ljava/lang/String;)V
#15 = Utf8               args
#16 = Utf8               [Ljava/lang/String;
#17 = Utf8               x
#18 = Utf8               I
#19 = Utf8               y
#20 = Utf8               a
#21 = Utf8               b
#22 = Utf8               SourceFile
#23 = Utf8               MethodAreaDemo.java
#24 = NameAndType        #6:#7          // "<init>":()V
#25 = Class              #31            // java/lang/System
#26 = NameAndType        #32:#33        // out:Ljava/io/PrintStream;
#27 = Class              #34            // java/io/PrintStream
#28 = NameAndType        #35:#36        // println:(I)V
#29 = Utf8               com/atguigu/java1/MethodAreaDemo
#30 = Utf8               java/lang/Object
#31 = Utf8               java/lang/System
#32 = Utf8               out
#33 = Utf8               Ljava/io/PrintStream;
#34 = Utf8               java/io/PrintStream
#35 = Utf8               println
#36 = Utf8               (I)V

三 字节码执行过程展示

1 执行前,方法区、虚拟机栈以及程序计数器的样子

方法区使用举例

2 将操作数 500 放入到操作数栈中。

方法区使用举例

3 弹出操作数栈栈顶 500,保存到本地变量表1。

方法区使用举例

4 把 100 这个数值压入操作数栈

方法区使用举例

5 弹出操作数栈栈顶 100,保存到本地变量表2。

方法区使用举例

6 读取本地变量1压入操作数栈

方法区使用举例

7 读取本地变量2压入操作数栈

方法区使用举例

8 将栈顶两个 int 类型取出并相除,结果5入栈。

方法区使用举例

9 将5保存到本地变量3,然后将50压入操作数栈

方法区使用举例

10 将栈顶 int 类型值保存到局部变量表4中。

方法区使用举例

11 获取类或接口字段的值并将其压入操作数栈

#2 在常量池经过一番拼接,最终拼接成: java/lang/System.out:Ljava/io/PrintStream,它是Fieldref 类型。

方法区使用举例

12 将本地变量3取出,压入操作数栈。

方法区使用举例

13 将本地变量4取出,压入操作数栈。

方法区使用举例

14 将栈顶两个 int 类型取出并相加,结果55入栈。

方法区使用举例

15 调用 invokevirtual #3 #3 = Methodref          #27.#28        // java/io/PrintStream.println:(I)V

方法区使用举例

16 main方法执行结束,进行 return

方法区使用举例

整个过程中,程序计数器始终计算的都是当前代码运行的位置,目的是为了方便记录方法调用后能够正常返回,或者是进行了 CPU 切换后,也能回来到原来的代码进行 执行。

上一篇:2021-07-12


下一篇:C++ JNI jstring to string (utf16 to utf8)