JVM内存模型详解

文章目录

    • [1. 程序计数器(Program Counter Register)](#1. 程序计数器(Program Counter Register))
    • [2. Java虚拟机栈(Java Virtual Machine Stacks)](#2. Java虚拟机栈(Java Virtual Machine Stacks))
    • [3. 本地方法栈(Native Method Stacks)](#3. 本地方法栈(Native Method Stacks))
    • [4. Java堆(Java Heap)](#4. Java堆(Java Heap))
    • [5. 方法区(Method Area)](#5. 方法区(Method Area))
      • [运行时常量池(Runtime Constant Pool)](#运行时常量池(Runtime Constant Pool))
    • [直接内存(Direct Memory)](#直接内存(Direct Memory))

JVM内存模型主要指的是Java虚拟机在运行时管理内存的方式,以及它如何保证线程之间规范而安全地共享数据。JVM内存模型可分为几个关键区域,各自负责不同的功能:

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

  • 作用:程序计数器是一块较小的内存空间,用于记录当前线程所执行的字节码指令的地址,帮助CPU知道下一条要执行的指令。如果线程正在执行的是Java方法,计数器记录的是字节码指令的地址;如果正在执行的是本地(Native)方法,计数器值则为空(Undefined)。
  • 线程私有:每个线程都有一个独立的程序计数器,互不影响。
  • 无内存溢出 :程序计数器是唯一一个在《Java虚拟机规范》中没有规定任何OutOfMemoryError情况的区域

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

  • 作用 :Java虚拟机栈是线程私有的,用于描述Java方法执行的线程内存模型。每个方法执行时会创建一个栈帧,用于存储局部变量表、操作数栈、动态链接、方法出口等信息。
    • 局部变量表存放了编译期可知的各种Java虚拟机基本数据类型(boolean、byte、char、short、int、 float、long、double)、对象引用(reference类型)
    • 这些数据类型在局部变量表中的存储空间以局部变量槽(Slot)来表示,其中64位长度的long和double类型的数据会占用两个变量槽,其余的数据类型只占用一个。局部变量表所需的内存空间在编译期间完成分配,在方法运行期间不会改变局部变量表的大小。
  • 异常情况 :如果线程请求的栈深度大于虚拟机允许的最大深度,将抛出StackOverflowError异常;如果栈扩展失败,将抛出OutOfMemoryError异常。

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

  • 作用:线程私有,与虚拟机栈类似,但为虚拟机使用的本地(Native)方法服务。
  • 异常情况 :与虚拟机栈类似,本地方法栈也会在栈深度溢出或栈扩展失败时分别抛出StackOverflowErrorOutOfMemoryError异常。

4. Java堆(Java Heap)

  • 作用:Java堆是所有线程共享的一块内存区域,用于存放对象实例。几乎所有的对象实例都在这里分配内存。
  • 垃圾回收:Java堆是垃圾收集器管理的主要区域,因此也被称为"GC堆"。
  • 异常情况 :如果堆中没有内存完成实例分配,并且堆也无法再扩展时,Java虚拟机将会抛出OutOfMemoryError异常。
  • 从分配内存的角度看,所有线程共享的Java堆中可以划分出多个线程私有的分配缓冲区(Thread Local Allocation Buffer,TLAB)。在多线程环境中,堆内存是线程共享的,因此对象分配时需要同步操作,这会导致性能下降。TLAB通过为每个线程分配独立的内存空间,避免了多线程之间的内存分配竞争,从而提高了内存分配效率。

5. 方法区(Method Area)

  • 作用:逻辑概念,方法区是线程共享的内存区域,用于存储已被虚拟机加载的类信息、常量、静态变量等数据。
  • 异常情况 :当方法区无法满足新的内存分配需求时,将抛出OutOfMemoryError异常。
  • JDK 8的变化:JDK 8及之后的版本将方法区存放在元空间(Metaspace)中,元空间位于操作系统维护的直接内存中。

运行时常量池(Runtime Constant Pool)

  • 是方法区的一部分,class文件中除了有类的版本、字段、方法、接口等描述信息外,还有一项信息是常量池表(Constant Pool Table),常量池表中存放了编译期生成的各种字面量和符号引用,具备动态性。
  • 当常量池无法再申请到内存时会抛出OutOfMemoryError异常。

直接内存(Direct Memory)

实际上是本机物理内存

  • 作用 :直接内存不是虚拟机运行时数据区的一部分,但会被频繁使用。它用于NIO等操作,通过Unsafe类直接分配内存。
  • 异常情况 :可能导致OutOfMemoryError异常。
相关推荐
学到头秃的suhian3 小时前
JVM-类加载机制
java·jvm
NEFU AB-IN9 小时前
Prompt Gen Desktop 管理和迭代你的 Prompt!
java·jvm·prompt
唐古乌梁海15 小时前
【Java】JVM 内存区域划分
java·开发语言·jvm
众俗15 小时前
JVM整理
jvm
echoyu.16 小时前
java源代码、字节码、jvm、jit、aot的关系
java·开发语言·jvm·八股
代码栈上的思考1 天前
JVM中内存管理的策略
java·jvm
thginWalker1 天前
深入浅出 Java 虚拟机之进阶部分
jvm
沐浴露z1 天前
【JVM】详解 线程与协程
java·jvm
thginWalker1 天前
深入浅出 Java 虚拟机之实战部分
jvm
程序员卷卷狗3 天前
JVM 调优实战:从线上问题复盘到精细化内存治理
java·开发语言·jvm