【JVM —— 04 JVM 运行时数据区】

JVM 运行时数据区是 JVM 在执行 Java 程序时用来管理内存的区域。这些区域各自有不同的职责和生命周期。

  • 程序计数器(Program Counter Register)
  • Java 虚拟机栈(Java Virtual Machine Stack)
  • 本地方法栈(Native Method Stack)
  • 堆(Heap)
  • 方法区(Method Area)

 

1. 程序计数器(Program Counter Register)

        程序计数器是一个小型的内存空间,它可以看作是当前线程所执行的字节码的行号指示器。每个线程都有一个独立的程序计数器,用来记录当前线程所执行的字节码的地址。如果线程正在执行的是一个本地方法(Native Method),这个计数器的值则是未定义的。

2. Java 虚拟机栈(Java Virtual Machine Stack)

        Java 虚拟机栈是线程私有的,生命周期与线程相同。每个方法在执行时都会创建一个栈帧(Stack Frame),用来存储局部变量表、操作数栈、动态链接、方法出口等信息。每一个方法从调用到执行完成的过程,就对应一个栈帧在虚拟机栈中从入栈到出栈的过程。

3. 本地方法栈(Native Method Stack)

        本地方法栈与 Java 虚拟机栈类似,不过它为虚拟机使用到的本地方法服务。本地方法栈也可以与特定语言的处理器或系统接口有关。它也是线程私有的,生命周期与线程相同。

4. 堆(Heap)

        堆是所有线程共享的一块内存区域,主要用来存储对象实例。几乎所有的对象实例都在堆上分配。堆是垃圾收集器管理的主要区域,因此常被称作 GC 堆。Java 堆可以处于物理上不连续的内存空间中,只要逻辑上是连续的即可。根据需要,Java 堆还可以被分成多个区域,如新生代和老年代。

5. 方法区(Method Area)

        方法区也是各个线程共享的内存区域,用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。虽然 Java 虚拟机规范将方法区描述为堆的一个逻辑部分,但它却有一个别名叫“非堆”(Non-Heap)。在 JDK 7 之前,方法区的实现称为永久代(Permanent Generation),从 JDK 8 开始,永久代被移除了,取而代之的是元空间(Metaspace)。

6. 运行时常量池(Runtime Constant Pool)

        运行时常量池是方法区的一部分。它用于存放编译期生成的各种字面量和符号引用,这部分内容将在类加载后存放到方法区的运行时常量池中。运行时常量池相对于 Class 文件常量池的一个重要特征是具备动态性,Java 语言并不要求常量一定只有编译期才能产生,运行期间也可以将新的常量放入池中(如 String 类的 intern() 方法)。

7. 直接内存

直接内存(Direct Memory)并不在《Java虚拟机规范》中存在,所以并不属于Java运行时的内存区域。

在 JDK 1.4 中引入了 NIO 机制,使用了直接内存,主要为了解决以下两个问题:

1、Java堆中的对象如果不再使用要回收,回收时会影响对象的创建和使用。

2、IO操作比如读文件,需要先把文件读入直接内存(缓冲区)再把数据复制到Java堆中。

现在直接放入直接内存即可,同时Java堆上维护直接内存的引用,减少了数据复制的开销。写文件也是类似的思路。

使用堆创建对象的过程:

使用直接内存创建对象的过程,不需要进行复制对象,数据直接存放在直接内存中:

  • 13
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值