浅析JVM内存模型

  • Java虚拟机内存
    ​  Java虚拟机在执行Java程序的时候会将它管理的内存分为若干个不同的数据区域。不同的区域用途也各不相同,具体内存模型图如下图所示:
    Java内存模型.png

      其中橙色部分为线程私有的数据区域,蓝色部分为线程共享的数据区域
    程序计数器
      程序计数器是一块较小的内存空间,主要记录当前线程执行的虚拟机字节码地址,如果执行的是Native方法,则程序计数器值为空。
    虚拟机栈
      虚拟机栈描述的是Java方法的内存模型:每个方法在执行的时候都会创建一个栈帧,用来存储局部标量表、操作数栈、动态链接、方法出口等信息
    本地方法栈
      本地方法栈与虚拟机栈作用相似,不同的是本地方法栈是用于描述Native方法的内存模型

      Java堆是Java虚拟机所管理内存中最大的一块,也是被所有线程共享的一块内存区域,该区域主要是存放对象实例。Java堆也是垃圾收集器的主要区域,从内存回收的角度来看,由于现在收集器基本都采用分代收集算法,所以Java堆还可以细分为新生代和老年代,再细致一点的有Eden空间、From Survivor空间、To Survivor空间等
    方法区
      方法区也是被各个线程共享的内存区域,主要用于存储被虚拟机加载的类信息、常量静态变量、即时编译器编译后的代码等数据
  • Java虚拟机是如何操作这些区域的

结合代码重点了解一下JVM运行时数据区,主要是虚拟机栈的分析

com.kons;

public class Test{
   public static void main(String[] args){
       int a=1;
       int b=2;
       int c=add(a,b);
   }
   
   public static int add(int a,int b){
       return a+b;
   }
}

首先Test类被编译成class文件,通过类加载子系统加载到内存中。然后,JVM会给执行的线程分配程序计数器、虚拟机栈、以及本地方法栈,如图所示:

虚拟机栈.png

当执行main方法的时候,会给main方法创建一个栈帧压入虚拟机栈中,同理,当执行到add方法时也是如此,如图所示:

入栈.png

栈帧内部主要由局部变量,操作数栈,动态链接以及方法出口等及部分组成,接下来结合class文件了解一下,这个栈帧具体是怎么工作的。

打开class文件所在文件夹,通过javap命令查看class文件

javap -c Test.class >test.txt

代码如图所示:

Compiled from "Test.java"
public class Test {
  public Test();
    Code:
       0: aload_0
       1: invokespecial #1                  // Method java/lang/Object."<init>":()V
       4: return

  public static int add(int, int);
    Code:
       0: iload_0
       1: iload_1
       2: iadd
       3: ireturn

  public static void main(java.lang.String[]);
    Code:
       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: return
}

执行流程

iconst_1:将整数1推到操作数栈上
istore_1:栈顶元素出栈并存入局部变量表1号位
iconst_2:将整数2推到操作数栈上
istore_2:栈顶元素出栈并存入局部变量表2号位

stack.png

iload_1:将局部变量表1号位元素放入栈顶
iload_2:将局部变量表2号位元素放入栈顶

iload.png

invorkestatic:调用静态方法add,该指令将弹出栈顶数据作为方法的参数并放入add栈帧中的局部变量表中

add.png

iload_0,iload_1:将局部变量表的数据压入操作数栈

add_load.png

执行到iadd的时候,操作数栈将数据相加并压入栈,执行完后,通过方法出口返回到main方法,并将add栈帧弹出虚拟机栈,最后通过istore指令将返回的数据存入局部变量表中

return.png

参考资料
《深入Java虚拟机》

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

友情链接更多精彩内容