JVM-内存结构

发布于:2025-06-06 ⋅ 阅读:(24) ⋅ 点赞:(0)

🧩 一、JVM内存五大核心结构详解

📌 1. 程序计数器(Program Counter Register)
特性 说明
作用 记录当前线程执行的字节码行号指示器(分支/循环/异常处理的核心)
线程私有 ✅ 每个线程独立存储指令位置
异常 ❌ 唯一不会抛出OutOfMemoryError的区域
特殊场景 ⚠️ 执行Native方法时值为undefined

📦 2. 虚拟机栈(Java Virtual Machine Stack)
// 栈帧内存模型示例
public void calculate() {
    int a = 1;                  // → 局部变量表(基本类型)
    Object obj = new Object();  // → 引用存栈,对象实例在堆
    obj.toString();             // → 动态链接指向方法区的方法字节码
}

虚拟机栈是JVM执行Java方法的运行时数据结构,通过栈帧为每个方法调用提供隔离的执行环境,管理局部数据存储和运算过程,构建完整的方法调用链

组件 作用
局部变量表 存储基本类型(int/boolean等)和对象引用(reference指针)
操作数栈 执行计算指令的临时工作区(如加减乘除)
动态链接 指向运行时常量池的方法符号引用(关联方法区)
方法出口 记录方法返回地址(正常return或异常退出)
异常 ⚠️ StackOverflowError(递归过深)
⚠️ OOM(扩展栈内存失败)

🌍 3. 本地方法栈(Native Method Stack)
特性 说明
作用 为JNI(Java Native Interface)方法提供内存空间(C/C++代码)
线程私有 ✅ 与虚拟机栈隔离
异常 ⚠️ 同虚拟机栈(StackOverflowError/OOM)
关键差异 🔄 服务Native方法而非Java方法(但HotSpot将两栈合并)

🗃️ 4. 堆(Heap)
JVM堆内存
年轻代
老年代
Eden区
Survivor区
S0区
S1区

内存比例

  • -XX:NewRatio=2:老年代:年轻代=2:1(默认)
  • -XX:SurvivorRatio=8:Eden:S0:S1=8:1:1

对象晋升规则

年龄1
年龄2
年龄3
年龄>15
年龄>15
大对象
对象创建
Eden区
S0区
S1区
老年代
特性 说明
线程共享 ✅ 所有线程访问同一堆空间
存储内容 对象实例、数组、字符串常量池(JDK7+)
GC机制 分代回收:
- 新生代(Minor GC)
- 老年代(Full GC)
异常 ⚠️ OutOfMemoryError(内存泄露/大对象)
配置参数 -Xms(初始堆大小)
-Xmx(最大堆大小)

📚 5. 方法区(Method Area)
版本 实现名称 存储位置 内容 参数配置
JDK7- 永久代 JVM内存 类元数据/运行时常量池/静态变量 -XX:PermSize
JDK8+ 元空间 本地内存 类元数据/运行时常量池 -XX:MaxMetaspaceSize
共性 JIT编译代码/方法字节码

💡 重大变革
静态变量在JDK7后存入堆中!字符串常量池在JDK7从永久代移至堆。


🔤 二、常量池体系解析

常量池分为三级结构,关系如下:

类加载
字符串解析
Class文件常量池
运行时常量池
字符串常量池
1. Class 文件常量池 (Constant Pool)
  • 位置.class文件中的固定结构
  • 内容
    字面量:字符串、数值等显式常量
    String s = "fly";  // "fly" 即字面量
    
    符号引用
    → 类/接口的全限定名(如java/lang/Object
    → 字段名和描述符(如Ljava/lang/String;
    → 方法名和描述符(如()V
  • 特点
    → 编译期生成
    静态存储(不依赖运行时)
2. 运行时常量池 (Runtime Constant Pool)
  • 位置:方法区的一部分(JDK8+在元空间)
  • 生成过程
    → 类加载时,将Class文件常量池加载到内存
    符号引用 → 解析为 直接引用(指向方法/字段的内存地址)
  • 动态性
    ✅ 支持运行时添加常量(如String.intern()
    ✅ 存储内容:
    → 类/方法解析后的直接引用
    → 数值/字符串等基本常量
3. 字符串常量池 (String Table)
  • 位置演变

    JDK版本 位置 原因
    JDK6 方法区 受永久代大小限制,易OOM
    JDK7+ 堆内存 允许GC回收,避免OOM;调优更灵活
  • 核心机制

    // 示例1:直接赋值(优先使用常量池)
    String s1 = "fly";                // 在常量池创建对象
    String s2 = "fly";                // 复用常量池对象(s1 == s2)
    
    // 示例2:new创建(堆中新对象)
    String s3 = new String("fly");    // 堆中创建新对象(s1 ≠ s3)
    
    // 示例3:intern主动入池
    String s4 = s3.intern();          // 返回常量池引用(s1 == s4)
    
  • 设计优势
    避免重复创建:相同字符串共享内存
    GC可回收:JDK7+后可被垃圾回收


常量池对比总结

特性 Class文件常量池 运行时常量池 字符串常量池
存在阶段 编译期(.class文件) 运行期(方法区/元空间) 运行期(堆)
是否可动态添加 ✅(intern等) ✅(intern强制入池)
内容 字面量+符号引用 直接引用+运行时添加的常量 唯一字符串的引用
内存回收 不支持 JDK8+由元空间管理 JDK7+支持GC回收
OOM风险 元空间溢出 堆内存溢出

网站公告

今日签到

点亮在社区的每一天
去签到