Java虚拟机运行时数据区域详解

本文深入探讨Java虚拟机(JVM)的内存管理机制,详细解释程序计数器、虚拟机栈、本地方法栈、方法区及堆的作用与运作流程。通过示例程序,清晰展示线程、方法调用及对象生命周期的全过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

之前有篇文章写了Java虚拟机的内存管理
本篇文章详细写运行时数据区域。

程序计数器: 记录当前运行所在的行数。
为什么要设计程序计数器?

我们知道,CPU是根据时间片来进行调度的。当时间到达之后,CPU资源就给了其他线程。但是这个时候我们线程还没执行完毕。那后面再次获取时间片的时候我们要如何恢复线程呢?就是通过程序计数器。恢复到上次执行的哪一行。

虚拟机栈: 是线程独有的。我们肯定通过栈帧,这个说法。每个线程有自己的栈,先进后出。
看示例程序一。我们的线程先调用main方法,然后调用funB方法,funB在调用funA。栈里面存的什么?栈帧是针对方法来说:先main方法入栈,再funB入栈。再funA入栈。
funA里面过程:

  • 5 6 入操作数栈,进行相加等于11 将11出栈赋值给局部变量C(局部变量表)
  • 将11入栈,5入栈 进行相乘,将结果55出栈,赋值给局部变量C
  • 将C返回。方法出口记录的 funB的int c = funA(a,b)所在的行

知道过程。对栈里面存储什么就应该清楚了
存储:局部变量表(基础数据类型,引用类型)。操作数栈(所有的操作都是在这里完成。最后一定是空的)。动态链接(有时候,编译完成是不知道引用的是哪个类的(多态)。记录符号引用)。方法出口(记录方法执行完毕后,下一个指令的行号)

在这里插入图片描述

// 示例程序1
public class JvmTest {
	private int temp;
    private int funA(int a, int b){
        int c = a + b;
        c = c * 5;
        return c;
    }
    private void funB(){
        int a = 5;
        int b = 6;
        int c = funA(a, b);
        System.out.println(c);
    }
    public static void main(String[] args) {
        JvmTest jvmTest = new JvmTest();
        jvmTest.funB();
    }
}

本地方法栈 过程同虚拟机栈,只不过虚拟机栈是执行Java方法。本地方法栈执行的是C方法(因为很多库函数是C写的。之前也没得java)

方法区 我之前因为方法区是永久代。但是我后面又看了深入理解Java虚拟机第三版。方法区JDK1.8之后不在永久代。在元空间里面。就是直接内存。 里面存储类信息(为什么反射能够在运行时找到类的所有信息。因为就存在方法区里)。现在应该能够理解方法区存什么了吗。存储类信息:例如方法,静态变量,运行时常量。以及其他信息

: 存储具体的实例。对象头(锁信息,分代年龄,其他)+ 实例数据(例如 示例程序里面,实例jvmTest里面其实就能存储了 temp=0)+ 占位符

需要注意的是:实例存在在堆里面。栈里面是有些对象变量。或常量,那个是存储的对象的地址。就是一个指向堆里某个位置的引用。

现在将我的示例程序运行过程描述一遍

  1. 程序启动,先加载类。将类信息全部加载到方法区(类有哪些变量,有什么方法) 【方法区-线程共享】
  2. 启动线程运行。先将main方法入栈。 【虚拟机栈-线程独有】
  3. 创建一个jvmTest对象:在堆新建一个jvm对象:包含对象头,实现信息temp=0,填充数据 【堆-线程贡献】
  4. 调用funB,将funB入栈。【虚拟机栈】
  5. 加载局部变量(a,b)到局部变量表 【虚拟机栈】
  6. 调用funA,将funA入入栈。 加载局部变量,并进行运行。【虚拟机栈】
  7. 计算出C并返回后,funA出栈【虚拟机栈】
  8. 打印C的值后,funB()出栈。【虚拟机栈】
  9. main方法结束,main出栈线程结束【线程死亡,全部已经出栈,这块内存已经释放】
    10.垃圾回收运行,回收jvmTest对象【释放堆空间】

有没有留意到:栈空间释放了,堆空间也释放了。程序计数器(线程里面,记录行数的,没运行一步,其值就会改变,线程没了)也释放了。但是方法区空间好像没有释放?
在深入理解java虚拟机里面,作者有说:方法区条件释放很苛刻。下面3者缺一不可:
①所有该对象的实例已经被回收。包括其子类的对象
②给类的类加载器已经被回收
③该类的Class对象也已经被回收

  												路漫漫其修远兮,吾将上下而求索
  												博主:五更依旧朝花落
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值