JVM运行流程/运行时数据区

JVM运行流程

程序在执行之前先要把 java代码 转换成 字节码文件 (.class文件), JVM 首先需要把字节码通过一定的方式 类加载器 (ClassLoader) 把文件加载到内存中 运行时数据区 (Runtime Data Area) , 而字节码文件是 JVM 的一套指令集规范, 并不能直接交给底层操作系统去执行, 因此需要特定的命令解析器 执行引擎 (Execution Engine) 将字节码翻译成底层系统指令再交由CPU去执行, 而这个过程中需要调用其他语言的接口 本地库接口 来实现整个程序的功能.

 总的来看, JVM主要通过以下四部分来运行Java程序:

  1. 类加载器
  2. 运行时数据区
  3. 执行引擎
  4. 本地库入口

通俗来讲 JVM 划分的区域就是:

  1. 堆: 存放的是 new 的对象.
  2. 方法区: 放的是 类对象. (加载好的类).
  3. 栈: 放的是方法之间的调用关系.
  4. 程序计数器: 放的是下一个要执行的指令的地址.

而在栈中还能分两部分:

  • 虚拟机栈 (Java 里面用来保存调用关系的内存空间)
  • 本地方法栈 (本地方法, 也就是 JVM 内部 C++ 写的代码, 调用关系的内存空间)

这里经常会有一个小的试题出现: 看代码.

package Test;

public class Demo {
    private int n = 10;
    private static int m = 20;

    public static void main(String[] args) {
        Demo demo = new Demo();
    }
}

问: 在当前代码中, n 在内存中的哪个区域? m 在内存中的哪个区域? demo 在内存中的那个区域?

答: n是成员变量, 就是在堆上.  m是静态变量, 在类对象里, 就是在方法区中. demo是局部变量, 就是在栈上. 

另一段代码:

package Test;

class A {
    private int x = 10;
}

public class Demo {
    private int n = 10;
    private static int m = 20;

    private static A a = new A();
    
    public static void main(String[] args) {
        Demo demo = new Demo();
    }
}

在看这段代码, 在这段代码中, 问: x 在内存中的哪个区域? a在内存中的哪个区域?

答: 首先 a 是静态的, 那么它仍然在方法区中, 但是它 new 的 A(), 还是在堆里, 所以 x 也是在堆里. 

内存划分

JVM 运行时数据区域也叫内存布局, 它由一下五个部分组成:

 

从上图我们可以看出, 是每一个线程都有的, 然后在图中是没有方法区的, 多了一个元数据区, 大家看到了吗, 方法区是 JDK1.7 之前的版本, 到了 1.8 之后, 把之前的方法区给去掉了, 弄出来这个元数据区, 他们两个的区别就是: 元数据区的内存不是在 JVM 中的, 之前方法区是在 JVM 申请到的这一大块内存里, 划分的区域. 元数据区呢是用的本地内存. 

  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

即将秃头的菜鸟

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

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

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

打赏作者

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

抵扣说明:

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

余额充值