Java探幽:1+1=2是怎么运行的?

本文通过一个简单的Java程序,来学习一下Java程序的内部执行过程。程序功能非常简单,就是计算1=1=2,代码如下:

public class JavaGo {

    public int add(int i1, int i2) {
        return i1 + i2;
    }

    public static void main(String[] args) {
        int sum = new JavaGo().add(1, 1);
        System.out.println(sum);
    }
}

可以看出上面这段简单的程序中,我们定义了如下几个关键部分:

  • 一个类JavaGo。
  • 一个成员方法add,包含两个参数,一个返回值。
  • 一个静态方法main。

然后 编译此代码文件,生成字节码文件JavaGo.class。

字节码

通过idea插件jclasslib看一下字节码的内容, Image

可以看到其中包含这个class的基本信息,常量池,还有接口、成员变量、方法、属性等。 其中常量池定义了本类中代码操作码使用到的常量,包括类名,变量名,字符串,常量数等。 我们来看看常量池中的内容: constantpool_javago.png

我们再看看main函数的操作码:

 0 new #2 <JavaGo>
 3 dup
 4 invokespecial #3 <JavaGo.<init>>
 7 iconst_1
 8 iconst_1
 9 invokevirtual #4 <JavaGo.add>
12 istore_1
13 getstatic #5 <java/lang/System.out>
16 iload_1
17 invokevirtual #6 <java/io/PrintStream.println>
20 return

其中操作码中的#n就表示引用的是常量池中的第n个常量。 字节码的解释到此为止。下面我们开始运行这段代码。

java -cp .\ JavaGo 输出为2

这段程序的背后到底发生了什么呢?

JVM

先来看看JVM的架构图:  

Image

JVM整体分为5个模块:

1.Class Loader:类装载器。

类装载包含如下三个步骤:

  • Loading : 装载.class文件,将类定义信息:类名、方法名、变量名等存入Method Area。
  • Linking:链接。包含如下3个阶段:
    • Verification: 校验。
    • Preparation: 准备,主要是给变量分配内存。
    • Resolution : 解析,主要是替换变量名为直接引用。
  • Initialization : 初始化。主要是给静态变量赋值。

2.JVM memory:存储器。

包含五部分:

  • Method Area/Metaspace: 方法/元数据空间,每个JVM一个,存放共享资源。包括各种类定义信息:类名,父类命,方法,变量等元信息,以及静态变量。
  • Heap Area:堆空间,每个JVM一个,存放所有对象实例。
  • Stack Area: 栈空间,每个线程一个,存放方法调用,方法内部变量等。每个对象类型的内部变量维护一个引用(句柄),指向堆空间的实例。
  • PC Registers:寄存器,每个线程一组,存放当前线程的运行指令。
  • Native method stacks :本地调用栈,每个线程一个,存放native方法信息。

3.Execution Engine:执行引擎。

包含如下三个模块:

  • Interpreter: 翻译器,线性翻译执行字节码指令。
  • JIT: 编译器,将频繁调用的字节码编译成机器码,提高效率。
  • GC:垃圾回收器。

4.JNI: 本地库调用接口。

5.Native Method Libraries: 本地库(C/C++)。

通过对JVM内部架构的了解,我们看到一个Java程序主要是通过类装载器装载.class文件, 然后解析出元数据,存储到内存中,再通过执行引擎,解释执行字节码指令,继而调用本地库来完成计算。

监控

最后通过Java自带的工具JVisualvm来监控一下我们的程序:  

Image

可以看到内存堆空间里已经生成了一个我们定义的对象实例。

参考列表

https://www.geeksforgeeks.org/jvm-works-jvm-architecture/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值