Java内存区域与对象结构探秘--运行时数据区域

1 程序计数器
  • 字节码的行号指示器
    • 寄存器,寄存了字节码解释器(两种执行引擎的一种)下一行要执行的字节码指令
  • 线程私有
    • 原因:jvm的多线程需要线程切换
  • 当执行的是本地方法时,计数器为空
  • 无OutOfMemoryError
2 Java虚拟机栈
  • 线程私有

  • 由栈帧组成

    • 每个方法执行时,JVM会创建一个栈帧用于存储局部变量表、操作数栈、动态连接、方法出口等信息。
    • 栈帧的入栈和出栈过程对应着方法的调用和执行完成。
  • 栈帧中的局部变量表

    • 存放基本数据类型、对象引用和returnAddress类型(指令地址)。

    • 数据存储以变量槽(Slot)表示,其中long和double占用两个变量槽,其他类型占用一个。

    • 局部变量表所需的空间在编译期分配,运行期间大小不变,大小指的是变量槽的数量。

  • 内存异常

    • StackOverflowError:栈深度溢出
    • OutOfMemoryError:栈扩展失败
3 本地方法栈
  • 与虚拟机栈类似,区别是为本地(Native)方法服务
  • 线程私有
  • 内存异常:
    • StackOverflowError:栈深度溢出
    • OutOfMemoryError:栈扩展失败
4 Java堆
  • 线程共享
    • 在虚拟机启动时创建
  • JVM管理的最大的一块内存区域
  • 用于存放对象实例
    • 几乎所有对象实例和数组都在堆上分配。
    • 随着Java语言的发展,例如即时编译和逃逸分析技术,一部分对象可能在栈上分配,但主要是堆分配。
  • 由垃圾收集器管理
    • Java堆又被称为GC堆(Garbage Collected Heap)。
    • 基于分代收集理论,堆通常分为新生代、老年代等区域,但这些划分并非Java虚拟机实际的内存布局,而是部分垃圾收集器共同的设计风格。
  • TLAB(Thread Local Allocation Buffer):
    • Java堆中可以有多个线程私有的TLAB,用于提高对象分配效率。
  • 物理和逻辑性质:
    • 物理上可以不连续,但逻辑上被视为连续。
    • 对大对象(如数组),多数JVM实现可能要求连续的内存空间。
  • 具体实现可以是固定大小也可以是可扩展的,但主流为可扩展。
  • 内存异常
    • OutOfMemoryError:如果堆无法分配更多实例且无法扩展。
5 方法区
  • 线程共享
  • 用于存储虚拟机加载的类型信息、常量、静态变量、即时编译后的代码等
  • 虽然《Java虚拟机规范》将方法区描述为堆的逻辑部分,但它通常被视为“非堆”(Non-Heap)以与Java堆区分。
  • 永久代与方法区的关系
    • 在JDK 8以前,HotSpot虚拟机中的方法区常被称为“永久代”(Permanent Generation),但这两者并不等价。
    • 永久代是旧版本JDK中HotSpot特有的实现,用于便于垃圾收集器管理这部分内存。
    • 到了JDK 8,已经完全废弃了永久代的概念,改用本地内存中的元空间(Metaspace)来实现方法区,与JRockit和J9虚拟机一致。
  • 《Java虚拟机规范》对方法区的规定相对宽松,可以不连续,可以固定大小或可扩展,可以不实现垃圾收集。
  • 内存异常
    • OutOfMemoryError:当方法区无法满足内存分配需求时
6 运行时常量池
  • 运行时常量池是方法区的一部分
  • 类文件中的常量池表(包含编译期生成的字面量和符号引用)在类加载后被存放到方法区的运行时常量池中
  • 运行时常量池除了保存Class文件中的符号引用,还会存储这些引用翻译出来的直接引用。
  • Java虚拟机规范对于运行时常量池的具体实现细节并没有明确要求。
  • 运行时常量池具备动态性,即在运行期间也可以将新的常量加入池中,例如String类的intern()方法的使用。
  • 内存异常
    • 由于运行时常量池是方法区的一部分,它受到方法区内存的限制。
    • OutOfMemoryError:当运行时常量池无法再申请到足够的内存时
7 字符串常量池
  • 仅在概念上是运行时常量池的一部分
  • 在Java 6及更早版本中,字符串常量池物理上位于永久代,即在物理上也是方法区的一部分
  • 但从Java 7开始,字符串常量池就被移动到Java堆内存中。并且,当java 8中永久代彻底被元空间取缔时,字符串常量池依旧位于Java堆内存中。
JVMJava Virtual Machine(Java虚拟机)的缩写,它是一种用于计算设备的规范,通过在实际的计算机上仿真模拟各种计算机功能来实现。JVM包括一套字节码指令集、一组寄存器、一个栈、一个垃圾回收堆和一个存储方法域。它的主要任务是运行Java程序,使得Java程序可以在多种平台上不加修改地运行。JVM在执行字节码时,实际上最终还是把字节码解释成具体平台上的机器指令执行。每个Java程序启动时都会产生一个JVM实例,当程序运行结束时,该实例也会消失。JVM是基于堆栈的虚拟机,为每个新创建的线程都分配一个堆栈,通过对堆栈的操作来完成Java程序的运行。JVM对堆栈进行以帧为单位的压栈和出栈操作。\[1\]\[2\]\[3\] #### 引用[.reference_title] - *1* [Java虚拟机Java Virtual Machine(JVM)总结(基于jdk 1.8)](https://blog.csdn.net/weixin_40923145/article/details/88602359)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* *3* [Java虚拟机JVM学习笔记](https://blog.csdn.net/x_panda/article/details/14215819)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值