JVM运行时数据区(Run-Time Data Areas)

JVM运行时数据区(Run-Time Data Areas)

    今天在网上搜索了关于JVM运行时数据区的介绍,发现很多人对于这个基础知识的理解偏差,简单列举几个比如
有人认为方法区在jdk8被移除了;

之后查阅了jdk8的JVM架构介绍,jdk11的JVM架构介绍 确定了一些事儿,先贴一张图,根据官方介绍自己画的.
在这里插入图片描述

pc寄存器(The pc Register)

  1. pc代表program counter,Java虚拟机可以支持多线程同时执行。
  2. 每个Java虚拟机线程都有自己的 pc(程序计数器)寄存器。
  3. 在任何时候,每个Java虚拟机线程都在执行单个方法的代码,即该线程的当前方法。
  4. 如果该方法不是native(本机底层)的,则pc寄存器包含当前正在执行的Java虚拟机指令的地址。如果线程当前执行的方法是native(本机底层)的,则Java虚拟机的pc寄存器的值是未定义的。
  5. Java虚拟机pc寄存器足够大,可以装下在特定平台上的返回地址或native(本机底层)指针。

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

  1. 每个Java虚拟机线程都有一个私有Java虚拟机堆栈,与线程同时创建。
  2. Java虚拟机堆栈存储栈帧。
  3. Java虚拟机堆栈类似于传统语言的堆栈,例如C:它保存局部变量和部分结果,并在方法调用和返回中起作用。由于除了进栈和出栈之外,永远不会直接操作Java虚拟机堆栈,因此可以对栈帧进行堆分配。Java虚拟机堆栈的内存不需要是连续的。

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

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

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

注意:以下异常与Java虚拟机堆栈有关:

如果线程中的操作或者计算需要更大的Java虚拟机堆栈,而需要的比提供的大,Java虚拟机将抛出StackOverflowError。

如果Java虚拟机栈允许动态地扩展,然后试图扩展时可以可用内存不足,则Java虚拟机将抛出OutOfMemoryError错误;如果没有足够的内存可用来为新线程创建初始Java虚拟机堆栈,则Java虚拟机将抛出OutOfMemoryError。

堆(Heap)

  1. 所有对象及其对应的实例变量和数组都存储在堆内存中;
  2. 这个内存区域是在JVM启动时创建的;
  3. 每个JVM只有一个堆区域跨多个线程共享,因为存储在该区域中的数据不是线程安全的;
  4. 如果存储在堆内存中的对象没有引用,则由垃圾回收器GC回收该对象的内存, 此区域中的对象从未显式释放;
  5. 堆的大小可以是固定的,也可以根据计算的需要进行扩展,如果不需要更大的堆,则可以收缩.
    以下异常情况与该区域有关:

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

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

如果需要更多的堆内存,而JVM提供的堆内存太小,Java虚拟机将抛出OutOfMemoryError。

方法区(Method Area)

  1. 保存每个.class文件的类级数据,如元数据、运行时常量池、静态变量、字段和方法数据,以及方法和构造函数的代码,包括类和实例初始化以及接口初始化中使用的特殊方法等。
  2. 方法区域类似于传统语言的编译代码的存储区域或类似于操作系统进程中的“文本”段。
  3. 每个JVM只有一个方法区域,并且在所有类之间共享。
  4. 分配给这个区域的内存默认情况下是由JVM分配的,或者可以根据计算需要增加。
  5. 方法区域是在虚拟机启动时创建的。
  6. 虽然方法区域在逻辑上是堆的一部分,但是对于一些简单的实现JVM可能选择不去垃圾回收或压缩它们。
  7. 方法区域可以是固定大小的,或者可以根据操作的需要进行扩展,并且如果不需要更大的方法区域时,则可以自动缩小方法区域。
  8. 方法区域的内存不需要是连续的。

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

注意:以下异常条件与方法区域相关联:

如果方法区域中的内存无法满足分配请求,则Java虚拟机会抛出一个OutOfMemoryError。
容易混淆的概念:方法区、永久代、元空间

方法区:是一个抽象的逻辑概念,或者说是一种规范,而永久代和元空间是方法区的两种实现方式;
永久代:jdk1.7以及jdk1.7之前的方法区的实现(指HotSpot VM),物理上在堆内存;
元空间:jdk1.8以及jdk1.8之后的方法区的实现,用来替换掉永久代(指HotSpot VM),物理上在直接内存。关于永久代的JVM参数也作废了,取而代之的MetaSpace空间的参数。元空间最大内存就是系统可利用最大内存,但是可通过MaxMetaspaceSize控制;

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

  1. 运行时常量池是类文件中constant_pool表的每个类或每个接口的运行时表示;
  2. 包括很多类型的常量,从编译时已知的数值常量到必须在运行时解析的方法和字段引用。
  3. 运行时常量池的功能类似于传统编程语言的符号表,尽管它包含的数据范围比典型符号表更广。
  4. 每个运行时常量池都是从Java虚拟机的方法区域中分配的。
  5. 当Java虚拟机创建类或接口时,将创建类或接口的运行时常量池。

注意:以下异常条件与方法区域相关联:

在创建类或接口时,如果运行时常量池的构造需要的内存比Java虚拟机的方法区域中可用的内存多,则Java虚拟机会抛出一个OutOfMemoryError。

本地方法堆栈(Native Method Stacks)

  1. Java虚拟机的实现可以使用传统堆栈(俗称“C堆栈”)来支持本机方法(用Java编程语言以外的语言编写的方法)。
  2. Java虚拟机指令集解释器的实现也可以使用本机方法堆栈,解释器使用的语言是C语言.无法加载本机方法且本身不依赖于传统堆栈的Java虚拟机实现不需要提供本机方法堆栈。
  3. 如果提供了本机方法堆栈,则通常在创建每个线程时为每个线程分配本机方法堆栈。
  4. 该规范允许本机方法堆栈具有固定的大小,或者根据计算的需要动态扩展和收缩。如果本地方法堆栈的大小是固定的,则可以在创建该堆栈时独立选择每个本机方法堆栈的大小。

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

注意:以下异常条件与本机方法堆栈相关联:

如果线程中的计算需要比允许的更大的本机方法堆栈,Java虚拟机将抛出StackOverflowError。

如果可以动态扩展本机方法堆栈,并且尝试进行本机方法堆栈扩展,但是没有足够的内存可用,或者没有足够的内存可用来为新线程创建初始本机方法堆栈,那么Java虚拟机将抛出OutOfMemoryError错误。

总结:

先简单总结几个,还需要再次总结.

  1. 线程共享区域:堆内存,方法区域
  2. 线程私有区域:pc寄存器,JVM堆栈,本地方法栈
  3. 方法区逻辑上属于堆内存
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值