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异常。
相关推荐
二十七剑1 小时前
jvm中各个参数的理解
java·jvm
七禾页话4 小时前
垃圾回收知识点
java·开发语言·jvm
小梁不秃捏1 天前
深入浅出Java虚拟机(JVM)核心原理
java·开发语言·jvm
xiaolingting1 天前
JVM层面的JAVA类和实例(Klass-OOP)
java·jvm·oop·klass·instanceklass·class对象
神仙别闹1 天前
基于Python+Sqlite实现的选课系统
jvm·python·sqlite
上分小子2.02 天前
jvm-Java虚拟机
java·开发语言·jvm
5xidixi2 天前
JAVA EE初阶 JVM
java·jvm·java-ee
北城以南没有天2 天前
排查JVM的一些命令
jvm
BUG研究员_2 天前
JVM深入理解
java·jvm·学习
小梁不秃捏2 天前
JVM 类加载器深度解析(含实战案例)
jvm·类加载器