Java核心基础——09 - Java内存区域

Java内存区域



一、Java运行时数据区域

在这里插入图片描述

程序计数器(The Register pc)

Java 虚拟机可以同时支持多个执行线程。 每个 Java 虚拟机线程都有自己的(程序计数器)寄存器。 在任何时候,每个 Java 虚拟机线程都在执行单个方法的代码,即该线程的当前方法。 如果该方法不是 ,则寄存器包含当前正在执行的 Java 虚拟机指令的地址。 如果线程当前正在执行的方法是 ,则 Java 虚拟机的寄存器的值是未定义的。 Java 虚拟机的寄存器足够宽,可以在特定平台上保存一个或一个本机指针。

程序计数器(pc寄存器):https://blog.csdn.net/m0_43408858/article/details/123205115

Java虚拟机堆栈(Java Virtual Machine Stacks)

每个 Java 虚拟机线程都有一个私有的 Java 虚拟机堆栈,与线程同时创建。 Java 虚拟机堆栈存储帧。 Java 虚拟机堆栈类似于 C 等传统语言的堆栈:它保存局部变量和部分结果,并在方法调用和返回中发挥作用。因为除了推送和弹出帧外,Java 虚拟机堆栈永远不会被直接操作,因此帧可能是堆分配的。 Java 虚拟机堆栈的内存不需要是连续的。

在 Java® 虚拟机规范的第一版中,Java 虚拟机堆栈被称为 Java 堆栈。

该规范允许 Java 虚拟机堆栈具有固定大小或根据计算要求动态扩展和收缩。如果 Java 虚拟机堆栈具有固定大小,则每个 Java 虚拟机堆栈的大小可以在创建堆栈时独立选择。

Java 虚拟机实现可以让程序员或用户控制 Java 虚拟机堆栈的初始大小,以及在动态扩展或收缩 Java 虚拟机堆栈的情况下,控制最大和最小大小。

以下异常情况与 Java 虚拟机堆栈相关:

如果线程中的计算需要比允许的更大的 Java 虚拟机堆栈,则 Java 虚拟机会抛出一个 .StackOverflowError

如果 Java 虚拟机堆栈可以动态扩展,并且尝试进行扩展,但没有足够的内存来影响扩展,或者如果没有足够的内存来为新线程创建初始 Java 虚拟机堆栈,则 Java Virtual机器抛出一个 .OutOfMemoryError

Java 虚拟机有一个在所有 Java 虚拟机线程之间共享的堆。堆是为所有类实例和数组分配内存的运行时数据区域。

堆是在虚拟机启动时创建的。对象的堆存储由自动存储管理系统(称为垃圾收集器)回收;对象永远不会被显式释放。 Java虚拟机假设没有特定类型的自动存储管理系统,存储管理技术可以根据实现者的系统要求来选择。堆可以是固定大小的,也可以根据计算的需要进行扩展,如果不需要更大的堆,则可以收缩。堆的内存不需要是连续的。

Java 虚拟机实现可以让程序员或用户控制堆的初始大小,如果堆可以动态扩展或收缩,还可以控制最大和最小堆大小。

以下异常情况与堆相关联:

如果计算需要的堆比自动存储管理系统提供的更多,Java 虚拟机会抛出一个 . OutOfMemoryError

方法区(Method Area)

方法区
Java 虚拟机有一个在所有 Java 虚拟机线程之间共享的方法区。方法区类似于传统语言的编译代码的存储区,或者类似于操作系统进程中的“文本”段。它存储每个类的结构,例如运行时常量池、字段和方法数据,以及方法和构造函数的代码,包括类和实例初始化和接口初始化中使用的特殊方法(第 2.9 节)。

方法区是在虚拟机启动时创建的。尽管方法区在逻辑上是堆的一部分,但简单的实现可能会选择不进行垃圾收集或压缩它。本规范不要求方法区域的位置或用于管理已编译代码的策略。方法区域可以是固定大小,也可以根据计算需要扩大,如果不需要更大的方法区域,可以缩小。方法区的内存不需要是连续的。

Java 虚拟机实现可以为程序员或用户提供对方法区域初始大小的控制,以及在方法区域大小可变的情况下,对最大和最小方法区域大小的控制。

以下异常情况与方法区相关:

如果方法区域中的内存无法满足分配请求,Java 虚拟机将抛出一个 .OutOfMemoryError

运行时常量池(Run-Time Constant Pool)

运行时常量池是文件中表的按类或按接口运行时表示(第 4.4 节)。它包含多种常量,从编译时已知的数字文字到必须在运行时解析的方法和字段引用。运行时常量池的功能类似于传统编程语言的符号表,尽管它包含比典型符号表更广泛的数据。常量池类

每个运行时常量池都是从 Java 虚拟机的方法区(第 2.5.4 节)分配的。类或接口的运行时常量池是在 Java 虚拟机创建类或接口时(第 5.3 节)构建的。

以下异常情况与类或接口的运行时常量池的构造有关:

创建类或接口时,如果构建运行时常量池需要的内存超出 Java 虚拟机的方法区域可用的内存,Java 虚拟机将抛出 .OutOfMemoryError

本地方法堆栈(Native Method Stacks)

Java虚拟机的实现可以使用常规堆栈(俗称“C堆栈”)来支持方法(用Java编程语言以外的语言编写的方法)。本机方法堆栈也可以由一种语言(如 C. Java 虚拟机)的指令集的解释器实现来使用,这些语言无法加载方法并且本身不依赖于传统堆栈的 Java 虚拟机实现不需要提供本机方法堆栈。如果提供,则本机方法堆栈通常在创建每个线程时为每个线程分配。

参考文档:https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-2.html#jvms-2.5.1

JVM运行程序的步骤

  1. 开启线程,开辟堆栈空间,在程序计数器中存入第一条指令的地址
  2. jvm读取pc寄存器中的指令位置,pc自动+1
  3. 根据指令位置读取字节码文件中的操作码和操作数(如果存在)
  4. 运行指令(执行操作码定义的操作),包括实例化对象存入堆内存,压栈,存入局部变量,获取锁释放锁…

:CPU中的PC和JVM中的PC不是一回事,JVM中的PC存放的指令是由Java程序被编译后生成的字节码指令,程序的运行就是由JV运行这些字节码指令来完成的
以上为个人看法和观点,如有不正之处希望谅解并欢迎指正。

相关资源
字节码指令1(加载和存储)…
JVM的内存区域划分

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值