JDK之运行时数据区(Run-Time Data Areas)


在这里插入图片描述

1.概述

1.Run-Time Data Areas ,大家可以理解为我们的class代码在运行阶段,在JVM内存中是如何进行存储的;
2.大家注意下:有些是JVM启动的时候存储的,有些是请求调用的过程中线程创建的;

2.Run-Time Data Areas 具体区域

2.1.Java Virtual Machine Stacks 【虚拟机栈】

1.首先,栈是一种数据结构,特点是先进后出;
2
1.线程私有(每一个线程会创建一个栈),虚拟机栈描述的是 Java 方法执行的内存模型,每个方法在执行时会创建一个栈帧,
  栈帧中保存有局部变量表、操作数栈、动态链接和方法出口等。
2.粗略来讲 Java 内存区分为堆和栈,实际上『栈』指的往往是虚拟机栈中的局部变量表部分。

局部变量表中存放了编译期可知的各种基本数据类型、对象引用类型和 returnAddress 类型。方法运行期间局部变量表大小不变。

StackOverflowError [栈的深度不够用了]

在这里插入图片描述

异常 OutOfMemoryError

在这里插入图片描述

栈针结构 frame

关于栈针的详细介绍大家可以参考下面的地址

官网地址

https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-2.html#jvms-2.6
在这里插入图片描述

概念

1.A new frame is created each time a method is invoked.
  每次方法被调用的时候,栈针就会被创建;(也就是,每一个方法,就会创建一个栈针)

栈针构成

在这里插入图片描述
在这里插入图片描述

局部变量表(Local Variable)
1.所谓局部变量就是方法的参数,比如比如caculate(int p1,int p2,int p3),那么局部变量就是p1,p2,p3
2.局部变量是从索引0开始的,比如caculate(int p1,int p2,int p3),那么p1的index就是0,p2的index就是1,p3的index就是2;
3.大家注意下,下面发放中的caculate中result也是一个局部变量

在这里插入图片描述

操作树栈(Operand Stacks)
1.操作树栈,主要是执行的运行,实际上就是执行的过程中的操作流程
动态链接(Dynamic Linking)
1.我们可以认为程序在运行的过程中,根据具体的类型去选择具体的常量对象
  比如多态
方法返回地址 (Invocation Completion)
1.我们知道一个方法即一个栈针,方法处理有正常处理和异常处理之分
  无论是正常处理还是异常处理,都会返回一个栈针的地址,用于标示当前方法处理的位置;

图示说明出栈与入栈

package com.gaoxinfu.demo.jdk;

import org.junit.Test;
public class StackTest {

    @Test
    public void test(){
        c(1);
    }

    public void c(int p1){
        System.out.println("Methord c =" +p1);
        this.b(1);
    }

    public void b(int p1){
        System.out.println("Methord b =" +p1);
        this.a(1);
    }

    public void a(int p1){
        System.out.println("Methord a =" +p1);
    }
}

在这里插入图片描述

1.栈的数据结构是先进后出,这个是针对的同一个方法中,如果调用了其他的方法,那么必须等到被调用的方法完成之后,并且出栈之后
  接着执行该方法剩下的内容,执行完成出栈;
2.一个方法被调用就表示一个栈针;  

Java虚拟机栈在执行方法的时候到底发生了什么?

Person.java
package com.gaoxinfu.demo.jdk;

public class Person {
    private String name="gaoxinfu";
    private int age;
    private final double salary=100;
    private static String hobby="volleyball";

    public void say(){
        System.out.println("Person say ...");
    }
    public static int caculate(int op1,int op2){
        op1=3;
        int result=op1+op2;
        return result;
    }

    public static void main(String[] args) {
        System.out.println(caculate(1,2));
    }

}

之前我们知道通过javac 可以反编译成16进制的编码

在这里插入图片描述
在这里插入图片描述

上面这种对应着的是一些编译后的class的二进制(16进制),可读性不好,然后jdk又给我们提供了另外一种形式 javap -C Person.class
如下
通过javap -C 去反编译查询class文件 (这里一定要注意,后面的文件是Person.class不是Person.java文件)
localhost:jdk gaoxinfu$ ls -la
total 16
drwxr-xr-x  4 gaoxinfu  staff  128 Feb 20 12:26 .
drwxr-xr-x  3 gaoxinfu  staff   96 Feb 20 10:53 ..
-rw-r--r--  1 gaoxinfu  staff  489 Feb 20 10:58 Person.java
-rw-r--r--  1 gaoxinfu  staff  421 Feb 20 12:26 StackTest.java
localhost:jdk gaoxinfu$ pwd
/Users/gaoxinfu/demo-idea/demo-jdk/src/main/java/com/gaoxinfu/demo/jdk
localhost:jdk gaoxinfu$ javac Person.java 
localhost:jdk gaoxinfu$ ls -la
total 24
drwxr-xr-x  5 gaoxinfu  staff  160 Feb 20 16:11 .
drwxr-xr-x  3 gaoxinfu  staff   96 Feb 20 10:53 ..
-rw-r--r--  1 gaoxinfu  staff  862 Feb 20 16:11 Person.class
-rw-r--r--  1 gaoxinfu  staff  489 Feb 20 10:58 Person.java
-rw-r--r--  1 gaoxinfu  staff  421 Feb 20 12:26 StackTest.java
localhost:jdk gaoxinfu$ javap -c Person.class 
Compiled from "Person.java"
public class com.gaoxinfu.demo.jdk.Person {
  public com.gaoxinfu.demo.jdk.Person();
    Code:
       0: aload_0
       1: invokespecial #1                  // Method java/lang/Object."<init>":()V
       4: aload_0
       5: ldc           #2                  // String gaoxinfu
       7: putfield      #3                  // Field name:Ljava/lang/String;
      10: aload_0
      11: ldc2_w        #4                  // double 100.0d
      14: putfield      #6                  // Field salary:D
      17: return

  public void say();
    Code:
       0: getstatic     #7                  // Field java/lang/System.out:Ljava/io/PrintStream;
       3: ldc           #8                  // String Person say ...
       5: invokevirtual #9                  // Method java/io/PrintStream.println:(Ljava/lang/String;)V
       8: return

  public static int caculate(int, int);
    Code:
       0: iconst_3   #(Push the int constant <i> (-1, 0, 1, 2, 3, 4 or 5) onto the operand stack.
) 将常量值 3加载到操作树栈中
       1: istore_0 
       2: iload_0
       3: iload_1
       4: iadd
       5: istore_2
       6: iload_2
       7: ireturn

  public static void main(java.lang.String[]);
    Code:
       0: getstatic     #7                  // Field java/lang/System.out:Ljava/io/PrintStream;
       3: iconst_1
       4: iconst_2
       5: invokestatic  #10                 // Method caculate:(II)I
       8: invokevirtual #11                 // Method java/io/PrintStream.println:(I)V
      11: return

  static {};
    Code:
       0: ldc           #12                 // String volleyball
       2: putstatic     #13                 // Field hobby:Ljava/lang/String;
       5: return
}
localhost:jdk gaoxinfu$   
解析 {参考官网}

直接在下面的地址进行搜索关键词,如iconst_3 ,则搜索iconst,不要带后面_下划线和数字
https://docs.oracle.com/javase/specs/jvms/se8/html/index.html

在这里插入图片描述

1.上面解析出来的代码,实际上是字节码顺序执行的指令;
2.关于每一个指令是什么意思,大家可以参考下面的地址
https://docs.oracle.com/javase/specs/jvms/se8/html/index.html
 大家注意下,如iconst_3 其后面的3是参数
把反编译后的上面的指令输入的文件Person.txt文件中
localhost:jdk gaoxinfu$ javap -c Person.class >Person.txt
localhost:jdk gaoxinfu$ 

在这里插入图片描述
在这里插入图片描述

通过caculate()方法 我们去图示演示整个流程

欢迎大家下载
https://www.processon.com/diagraming/5e43aea1e4b06b291a6b4b70
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

2.2.The pc Register 【程序计数器】

2.3.Heap 【堆】

在这里插入图片描述

1.堆存储的资源,都是一些公共的资源,所有的线程可以共享;
2.堆存储的是class对象以及数组(数组本质上也是对象)

异常 OutOfMemoryError

在这里插入图片描述

2.4.Method Area 【方法区】

https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-2.html#jvms-2.5
在这里插入图片描述

1.方法区存储的资源,都是一些公共的资源,所有的线程可以共享;
2.方法区存储资源:
     2.1.类的结构信息:----->静态存储结构
     2.2.常量,静态变量

在这里插入图片描述

异常 OutOfMemoryError

在这里插入图片描述

2.5.Run-Time Constant Pool 【运行时常量池】

1.运行时常量池位于JAVA虚拟机的方法区;
2.

2.6.Native Method Stacks 【本地方法栈】

3.内存模型与运行时内存区的一个对应关系

在这里插入图片描述
在这里插入图片描述

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

东山富哥

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值