用一段代码来彻底弄明白java运行时数据区

之前自己在看书籍了解java内存结构的时候,说到java运行时数据区,很多资料书籍就是给一堆概念,头晕乎乎,索性,自己对着代码来理解一把

仅限 JDK 8+

public class HelloWorld {
    private static String message = "Hello, World!"; // 静态变量
    
    public static void main(String[] args) {
        HelloWorld h = new HelloWorld(); // 实例化对象
        int result = h.add(3, 5);        // 调用实例方法
        String messageLocal = message;   // 使用静态变量
        printMessage(messageLocal);      // 调用静态方法
    }

    public int add(int a, int b) {
        int sum = a + b; // 局部变量
        return sum;
    }

    public static void printMessage(String msg) {
        System.out.println(msg); // 调用本地方法(如System.out.println)
    }
}

JDK 8+ 运行时数据区划分

1. 元空间(Metaspace,替代方法区)
  • 存储内容

    • 类的元数据(类名、方法字节码、字段信息等)。

    • 运行时常量池(符号引用、字面量描述,如 "Hello, World!" 的符号引用)

    • 静态变量(如 message 的引用,但实际字符串值在堆中)。

  • 示例体现

    • HelloWorld 类的元信息(包括 mainaddprintMessage 的方法字节码)。

    • 符号引用(如 HelloWorld.add 方法的名称和签名)。

    • 静态变量 message 的引用(指向堆中的字符串常量池)。


2. 堆(Heap)
  • 存储内容

    • 所有对象实例(如 new HelloWorld() 创建的对象)。

    • 字符串常量池(实际字符串值,如 "Hello, World!" 的具体内容)。

  • 示例体现

    • new HelloWorld() 实例对象。

    • 字符串 "Hello, World!" 的实际值(存储在堆的字符串常量池中)。


3. 虚拟机栈(JVM Stack)
  • 存储内容

    • 每个线程私有的栈帧(局部变量表、操作数栈、动态链接、方法出口等)。

  • 示例体现

    • main 方法的栈帧:

      • 局部变量 args(参数,引用类型,指向堆中的 String[] 对象)。

      • h(指向堆中的 HelloWorld 对象)。

      • result(基本类型 int 的值)。

      • messageLocal(引用类型,指向堆中的字符串常量池)。

    • add 方法的栈帧:

      • 参数 a 和 b(基本类型 int 的值)。

      • 局部变量 sum(基本类型 int 的值)。


4. 本地方法栈(Native Method Stack)
  • 存储内容

    • 为 Native 方法(如 System.out.println 调用的底层 C/C++ 代码)服务的栈帧。

  • 示例体现

    • 调用 System.out.println 时触发的 Native 方法栈帧。


5. 程序计数器(Program Counter Register)
  • 存储内容

    • 当前线程执行的字节码指令地址。

  • 示例体现

    • 主线程执行到 int result = h.add(3, 5); 时,记录该方法调用的指令位置。


关键区别(JDK 8+ 特性)

  1. 元空间替代方法区

    • 元空间使用本地内存(Native Memory),不再受 -XX:PermSize 和 -XX:MaxPermSize 限制。

    • 运行时常量池(符号引用)属于元空间的一部分,但 字符串的实际值在堆中

  2. 字符串常量池的位置

    • JDK 7+ 后,字符串常量池从方法区移至堆中,因此 "Hello, World!" 的实际值存储在堆中。

总结(JDK 8+)

  1. 元空间:类的元数据、符号引用(运行时常量池)、静态变量引用。

  2. :对象实例、字符串常量池(实际字符串值)。

  3. 虚拟机栈:方法调用的局部变量和操作数。

  4. 本地方法栈:Native 方法的调用栈。

  5. 程序计数器:线程执行位置的记录。

通过这种划分,可以清晰理解代码中每个变量和对象在内存中的位置,这对分析内存泄漏、栈溢出、垃圾回收等问题非常有帮助!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值