专注于 JetBrains IDEA 全家桶,永久激活,教程
持续更新 PyCharm,IDEA,WebStorm,PhpStorm,DataGrip,RubyMine,CLion,AppCode 永久激活教程

5-运行时数据区

一.运行时数据区

一个class文件被classloader加载到内存,经过load/link/initialize三步之后,然后交给jvm的运行时引擎运行,运行的时候在内存里面是一个什么情况?

53_1.png

根据《Java虚拟机规范》的规定,Java虚拟机所管理的内存将会包括以下几个运行时数据区域。

程序计数器(Program Counter Register):是一块较小的内存空间,它可以看作是当前线程所执行的字节码的行号指示器。

java虚拟机栈(JVM stacks): 线程私有的,它的生命周期与线程相同。虚拟机栈描述的是Java方法执行的线程内存模型:每个方法被执行的时候,Java虚拟机都会同步创建一个栈帧(Stack Frame)用于存储局部变量表操作数栈动态连接方法出口等信息。

本地方法栈(Native Method Stacks):与虚拟机栈所发挥的作用是非常相似的,其区别只是虚拟机栈为虚拟机执行Java方法(也就是字节码)服务,而本地方法栈则是为虚拟机使用到的本地 (Native) 方法服务。

Java堆(Java Heap):是虚拟机所管理的内存中最大的一块。Java堆是被所有线程共享的一块内存区域,在虚拟机启动时创建。此内存区域的唯一目的就是存放对象实例,Java 世界里“几乎”所有的对象实例都在这里分配内存。

方法区(Method Area):是一种逻辑划分。与Java堆一样,是各个线程共享的内存区域,它用于存储已被虚拟机加载的类型信息(类名、访问修饰符、字段描述、方法描述等)、常量池(静态常量在编译器存入class文件常量池)、静态变量、即时编译器编译后的代码缓存等数据。

jdk1.8之前叫永久代(Perm Space)字符串常量位于Perm Space,FGC不会清理。

jdk1.8之后叫元数据区域(Meta Space )包含类型信息/运行时常量池(run-time constant pool)。字符串常量位于堆,会触发FGC。

直接内存(Direct Memory):jvm可以直接访问的内存(os管理的内存)。NIO,提高效率,实现zero copy。

53_2.png 53_3.png

二.分析java虚拟机栈(JVM stacks)

Frame(栈桢):用于存储局部变量表操作数栈动态连接方法出口等信息。每一个方法被调用直至执行完毕的过程,就对应着一个栈帧在虚拟机栈中从入栈到出栈的过程。

53_4.png

局部变量表(local variables):存放了编译期可知的各种Java虚拟机基本数据类型(boolean、byte、char、short、 int、 float、long、double)、对象引用。

操作数栈(operand stacks)

动态连接(dynamic linking):动态链接是一个将符号引用解析为直接引用的过程。java虚拟机执行字节码时,遇到一个操作码,操作码第一次使用一个指向另一类的符号引用,则虚拟机就必须解析这个符号引用。

方法出口(return address): a() -> b(),方法a调用了方法b, b方法的返回值放在什么地方

让我们从一个小demo分析一下jvm stacks是如何运作的。

public class Test1 {
    public static void main(String[] args) {
        int i = 1;
        i = i++;
//        i = ++i;
        System.out.println(i);
    }
}

输出:1

53_5.png

我们来分析一下字节码:

1、 icons_1 把1压入操作数栈(栈顶为1)
2、 istore_1 把1出栈存储到局部变量表索引为1的位置(i此时为1,栈为空)
3、 iload_1 把局部变量表索引为1的值压入操作数栈(栈顶为1)
4、 iinc 1 by 1 把局部变量表索引为1的值加1(i此时为2)
5、 istore_1 操作数栈出栈将值赋给局部变量表索引为1的位置(i此时为1,栈为空)

所以最终局部变量表索引为1位置(即i)的值为1。

再来看看这个小demo

public class Test1 {
    public static void main(String[] args) {
        int i = 1;
//        i = i++;
        i = ++i;
        System.out.println(i);
    }
}

输出:2

53_6.png

我们来分析一下字节码:

1、 icons_1 把1压入操作数栈
2、 istore_1 把1出栈存储到局部变量表索引为1的位置
3、 iinc 1 by 1 把局部变量表索引为1的值加1 (i此时为2)
4、 iload_1 把局部变量表索引为1的值压入操作数栈
5、 istore_1 操作数栈出栈将值赋给局部变量表索引为1的位置(i此时为2)

所以最终局部变量表索引为1位置(即i)的值为2。

文章永久链接:https://tech.souyunku.com/38426

未经允许不得转载:搜云库技术团队 » 5-运行时数据区

JetBrains 全家桶,激活、破解、教程

提供 JetBrains 全家桶激活码、注册码、破解补丁下载及详细激活教程,支持 IntelliJ IDEA、PyCharm、WebStorm 等工具的永久激活。无论是破解教程,还是最新激活码,均可免费获得,帮助开发者解决常见激活问题,确保轻松破解并快速使用 JetBrains 软件。获取免费的破解补丁和激活码,快速解决激活难题,全面覆盖 2024/2025 版本!

联系我们联系我们