jvm运行时数据子系统

46 阅读2分钟

jvm运行时数据子系统

jvm的运行时区域分为6部分

flowchart TD
A[JVM Runtime Data Areas]
A --> B[堆 Heap]
A --> C[虚拟机栈 JVM Stack]
A --> D[本地方法栈 Native Stack]
A --> E[程序计数器 PC Register]
A --> F[方法区 Method Area]
A --> G[直接内存 Direct Memory]

classDef jvm fill:#f9e6ff,stroke:#333
classDef heap fill:#e6f7ff,stroke:#3498db
classDef stack fill:#e8f5e9,stroke:#2ecc71
classDef meta fill:#ffe6cc,stroke:#ff9900
classDef native fill:#ffcccc,stroke:#e74c3c

class A jvm
class B heap
class C,D stack
class F meta
class G native


模块详细说明:

1. 堆 (Heap Area) 🧱

graph LR
    堆 --> Young[年轻代]
    堆 --> Old[老年代]
    Young --> Eden[伊甸区]
    Young --> S0[Survivor0]
    Young --> S1[Survivor1]
  • 职责:所有对象实例和数组的存储池
  • 特性
    • 所有线程共享
    • 生命周期:对象创建到垃圾回收
    • 区域划分:
      • 年轻代 (Eden, Survivor0, Survivor1)
      • 老年代 (Tenured)
      • G1/ZGC等新型回收器有不同的分区策略
  • 异常OutOfMemoryError 当无法分配新对象时

2. 方法区 (Method Area) 📚

graph TD
    MethodArea --> 类[类信息]
    MethodArea --> 常量池[运行时常量池]
    MethodArea --> 静态[静态变量]
    MethodArea --> JIT[JIT编译代码]
  • 职责:类结构信息存储中心
  • 关键内容
    • 类全名、父类/接口名
    • 方法字节码/字段描述符
    • 运行时常量池(重要子模块)
    • static final 常量
  • 演进
    • JDK7:字符串常量池移至堆中
    • JDK8+:被 Metaspace 取代(使用本地内存,如下图)
    graph LR
        RAM[物理内存] --> OS
        OS --> JVM_Heap[JVM堆空间]
        OS --> Native_Memory[本地内存空间]
        Native_Memory --> Metaspace
        Native_Memory --> DirectBuffer[直接内存]
        Native_Memory --> JNI_Memory[JNI内存]
    

3. Java 虚拟机栈 (JVM Stacks) 🧾

graph TB
    Stack --> 栈帧1[栈帧 - 方法A]
    Stack --> 栈帧2[栈帧 - 方法B]

    栈帧1 --> 局部变量[局部变量表]
    栈帧1 --> 操作数[操作数栈]
    栈帧1 --> 动态[动态链接]
    栈帧1 --> 返回[返回地址]
  • 线程关系:每线程独享一个栈

  • 核心功能:方法调用时压入栈帧,返回时弹出

  • 栈帧结构

    组件说明
    局部变量表基本类型 + 对象引用
    操作数栈字节码指令操作区
    动态链接指向常量池的引用
    返回地址方法退出后回到的位置
  • 异常StackOverflowError(深度超限)


4. 本地方法栈 (Native Method Stack) 🌐

graph LR
    NativeStack --> JNI[Java Native Interface]
    JNI --> Native[本地库]
  • 专用场景:执行非Java方法(如C/C++函数)
  • 与JVM栈区别
    • 无字节码操作
    • 直接调用操作系统API
    • 支持JNI规范的所有本地操作

5. 程序计数器 (Program Counter Register) 📍

graph LR
    PC[Java方法] --> 指令1[字节码指令地址]
    Native方法 --> undefined
  • 核心作用:保存下一条执行的字节码地址
  • 特殊性
    • 唯一没有 OutOfMemoryError 的区域
    • 线程私有,保证线程切换后能正确恢复
    • 执行本地方法时为 undefined

补充区域:

6.直接内存 (Direct Memory) ⚡

graph LR
    A[NIO Direct Buffer] --> B(Native Memory)
  • 非JVM规范区域
  • 用途:NIO使用的堆外内存
  • 优势:减少JVM堆与本地堆的数据拷贝
  • 管理:通过 Unsafe 类分配回收
  • 异常OutOfMemoryError(超出系统内存)

以下是一个清晰的 JVM 运行时数据区域示意图及其说明

flowchart TD
    A[JVM Runtime Data Areas]
    A --> B[Heap Area<br/>对象实例存储<br/>所有线程共享<br/>运行时常量池<br/>GC管理区域]
    A --> C[Method Area<br/>类元数据存储<br/>静态变量]
    A --> D[Java Virtual Machine Stacks<br/>线程私有<br/>栈帧管理]
    A --> E[Native Method Stack<br/>线程私有<br/>本地方法执行]
    A --> F[Program Counter Register<br/>线程私有<br/>指令位置记录]
    A --> G[Native Memory<br/>直接内存<br/>Matespace<br/>JNI<br/>mmap内存映射]

    B --> C1[Runtime Constant Pool<br/>符号引用解析<br/>字面量存储]

    D --> D1[Stack Frame 1]
    D --> D2[Stack Frame 2]

    D1 --> D1a[Local Variables<br/>局部变量]
    D1 --> D1b[Operand Stack<br/>操作数]
    D1 --> D1c[Dynamic Linking<br/>符号引用]
    D1 --> D1d[Return Address<br/>返回位置]

jvm 对象空间分配机制深度解析:指针碰撞 vs 空闲链表

java对象的内存布局

怎么判断对象存活

jvm各个垃圾收集器的工作原理