1. 运行时数据区

2020-11-14  本文已影响0人  进击的蚂蚁zzzliu

概述

JVM运行时数据区.png

JVM在执行Java程序会把内存大致划分成图中5个部分

1. 程序计数器

2. 虚拟机栈

虚拟机栈.png
2.1 局部变量表

局部变量表是一组变量值存储空间,用于存放方法参数和方法内部定义的局部变量。在 Java 程序编译为 Class 文件时,就在方法的 Code 属性的 max_locals 数据项中确定了该方法所需要分配的局部变量表的最大容量

JVM使用基于栈的指令集,相对于只用寄存器的指令集,指令比较简单;操作数存储在方法局部变量表中,通过load相关指令把操作数从局部变量表压栈到栈帧执行,再通过store相关指令把操作数从栈中写会局部变量表,其实局部变量表就相当于基于寄存器指令集中的寄存器用于存储局部变量,但是相对于寄存器使用局部变量表速度稍慢

--示例代码:
public void tests(String a){
    {
        int b = 4;
    }
    long c = 1L;
    int d = 5;
}

先执行 javac -g Demo.java先编译,然后执行javap -c -l -p -v Demo 输出反汇编信息:

--反汇编信息:
 public void tests(java.lang.String);
    descriptor: (Ljava/lang/String;)V
    flags: ACC_PUBLIC
    Code:
      stack=2, locals=5, args_size=2
         0: iconst_4
         1: istore_2
         2: lconst_1
         3: lstore_2
         4: iconst_5
         5: istore        4
         7: return
      LineNumberTable:
        line 7: 0
        line 9: 2
        line 10: 4
        line 11: 7
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
            0       8     0  this   Lzzzliu/JVM/Demo;
            0       8     1     a   Ljava/lang/String;
            4       4     2     c   J
            7       1     4     d   I
局部变量表

以上面代码为例分析下局部变量表:

  1. 局部变量表的容量是以变量槽为最小单位。一个变量槽可以存放一个32位以内的数据类型,有boolean/byte/char/short/int/float/reference/returnAddress 8种,long/double需要分配两个连续的变量槽;
  2. 局部变量是有作用域的,如果当前字节码程序计数器的值已经超过了某个变量的作用域,则这个变量对应的变量槽是可以交给其他变量重用的;
  3. 示例反汇编代码:
2.2 操作数栈

操作数栈是一个后进先出栈,栈中每一个元素都可以是任意的java数据类型。栈中元素的数据类型必须与字节码指令的序列严格匹配,例如iadd指令执行时,最接近栈顶的两个元素的数据类型必须为int;

2.3 动态连接

每个栈帧中都包含一个指向运行时常量池中该栈帧所属方法的引用,通过该引用可以找到Class的常量池;

2.4 方法返回地址

方法正常退出时,主调方法的程序计数器的值就可以作为返回地址,栈帧中可能会保存这个值;异常退出时,返回地址要通过异常处理器来确定,栈帧中一般不会保存这部分信息;

2.5 附加信息

与调试、性能收集等相关的信息;

3. 堆

堆时被所有线程共享的一块内存区域,几乎所有的对象实例都在这里分配内存。

4. 方法区

方法区是各个线程共享的内存区域,用于存储已经被虚拟机加载的类型信息、常量、静态变量、即时编译器编译后的代码缓存等Class(*.class)相关信息。

5. 本地方法栈

本地方法栈在虚拟机调用本地方法(Native方法)时使用

--------over---------

上一篇 下一篇

猜你喜欢

热点阅读