JVM的内存模型很多人都看过,周志明老师的《深入理解Java虚拟机》已经解释的很清楚了。但是只限于概念性的知识,关于底层的原理并没有做深入的阐述,下面我们通过一个实例代码来分析JVM内存模型之间的联系与各模块之间的底层原理,底层比较复杂,可能篇幅有点长,请耐心阅读,一定给你讲透彻,阅读本文建议同《深入理解JVM》这本书一起参考。

此处先上一段代码,以下通过代码逐步分析:


public class Math {
	public int compute(){          //一个方法对应一块栈帧内存区域
		int a=1;
		int b=2;
		int c=(a+b)*10;
		return c;
	}
	public static void main(String[] args) {
		Math math=new Math();
		math.compute();
	}
}

这段代码生成的字节码文件如下:


Compiled from "Math.java"
public class com.lucas.Demo1.Math {
  public static final java.lang.Integer CONATANT;

  public com.lucas.Demo1.Math();
    Code:
       0: aload_0
       1: invokespecial #1                  // Method java/lang/Object."<init>":()V
       4: return

  public int compute();
    Code:
       0: iconst_1
       1: istore_1
       2: iconst_2
       3: istore_2
       4: iload_1
       5: iload_2
       6: iadd
       7: bipush        10
       9: imul
      10: istore_3
      11: iload_3
      12: ireturn

  public static void main(java.lang.String[]);
    Code:
       0: new           #2                  // class com/lucas/Demo1/Math
       3: dup
       4: invokespecial #3                  // Method "<init>":()V
       7: astore_1
       8: aload_1
       9: invokevirtual #4                  // Method compute:()I
      12: pop
      13: return

  static {};
    Code:
       0: sipush        666
       3: invokestatic  #5                  // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
       6: putstatic     #6                  // Field CONATANT:Ljava/lang/Integer;
       9: return
}

还是先上最经典的那一幅JVM内存模型图:

我们先来分析虚拟机栈的内存结构(图中箭头可以不考虑,只是局部的图):

以上图片的名词在此不做解释,默认读者已经知道,我们主要探究每一块区域的底层原理。

以上java在执行时,线程main在虚拟机栈内存中开辟一块空间。每个方法按照顺序依次进栈,每一个方法在执行时开辟一个栈帧,栈帧中存储的信息见上图。下面依次解释每一个区域的作用:以下不讲定义,只是以上面代码为实例,加上作者本人的理解,如有偏差,请自行取舍。

局部变量表:

故名思意就是存放局部变量的,以上代码中,在 compute() 方法创建的栈帧的局部变量表中存放的是:a,b,c三个局部变量,在 main() 方法创建的栈帧的局部变量表中存放的是 math这个变量。

操作数栈:

在作者的理解看来,操作数栈就是一个中转站。
对照前面的字节码指令,我们可以很清晰的知道了每一步,虚拟机的底层干了哪些事。
第一步,执行iconst命令
将一个常量加载到操作数栈
这时我们可以看到操作数栈中有2个常量 1 和 2;

第二步:执行字节码指令istore,将整型类型值存入局部变量中,并将操作数栈的内存释放出来。

第三步:执行字节码指令:

    4: iload_1
    5: iload_2
    6: iadd
    7: bipush        10
    9: imul
    10: istore_3
    11: iload_3
    12: ireturn

:从局部变量中装载第一个int类型的值到操作数栈

以上图片难以准确的解释程序执行时JVM的执行流程,建议研究以上字节码文件,指令可查看字节码指令手册,其实研究JVM的工作流程,最好的方式就是研究字节码文件。

动态连接区域:

笔者尚未彻底明白。。。欢迎朋友们给我留言,交流

笔者理解的JVM图:

关于GC:

GC算法请参考我的另一篇文章:
https://blog.csdn.net/weixin_42146996/article/details/102571871

还是先上图:

上图我觉得已经解释的很详细了,笔者很懒,不想再多解释了