当前位置: 首页 > news >正文

JVM-内存结构

1. 程序计数器 (Program Counter Register)
  • 核心作用
    → 记录当前线程执行的字节码指令地址(行号指示器)
    → 线程切换后恢复执行的依据
  • 关键特性
    ✅ 线程私有(每个线程独立)
    ✅ 唯一 OutOfMemoryError 的区域
    ✅ 执行Native方法时值为 undefined
  • 内存占用
    极小的固定空间(通常可忽略)
2. 虚拟机栈 (Java Virtual Machine Stack)
  • 核心作用
    → 存储方法调用的 栈帧(Stack Frame)
    → 栈帧包含四个部分:

    组成部分功能
    局部变量表存储方法参数和局部变量(含对象引用reference
    操作数栈存放计算过程中的临时数据(如算术运算中间值)
    动态链接指向运行时常量池的方法引用(支持运行时绑定)
    方法返回地址记录方法结束后回到调用位置(正常返回/异常退出)
  • 关键特性
    ✅ 线程私有(栈深度默认1MB)
    ❗ 抛出 StackOverflowError(如无限递归)
    ❗ 抛出 OutOfMemoryError(扩展栈空间失败)

3. 本地方法栈 (Native Method Stack)
  • 核心作用
    → 为Native方法(C/C++实现)提供栈空间
    → 存储本地方法的调用信息
  • 关键特性
    ✅ 线程私有
    ⚠️ HotSpot 虚拟机中将虚拟机栈与本地方法栈合并实现
    ❗ 抛出 StackOverflowError/OutOfMemoryError
4. 堆 (Heap)
  • 核心作用
    → 存储所有对象实例数组

  • 内存分区

    Java Heap
    新生代 Young Generation
    老年代 Old Generation
    Eden区 80%
    Survivor区 20%
    Survivor0
    Survivor1
    • 新生代:新对象分配区(默认占堆1/3)
    • 老年代:长期存活对象区(默认占堆2/3)
  • 关键特性
    ✅ 线程共享(所有线程共享对象访问)
    ❗ 垃圾回收(GC)主要战场
    ❗ 抛出 OutOfMemoryError: Java heap space(对象无法分配)

5. 方法区 (Method Area)
  • 核心作用
    → 存储 类信息(字段/方法名)、运行时常量池静态变量JIT编译后代码

  • 演进历史

    JDK版本实现位置参数
    ≤JDK7永久代堆内存中-XX:PermSize/MaxPermSize
    ≥JDK8元空间本地内存-XX:MetaspaceSize
  • 关键特性
    ✅ 线程共享
    ❗ 抛出 OutOfMemoryError: Metaspace(类元数据过多)
    运行时常量池是方法区的核心部分


常量池体系详解

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

类加载
字符串解析
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风险元空间溢出堆内存溢出
http://www.xdnf.cn/news/791047.html

相关文章:

  • MAU算法流程理解
  • VueUse:组合式API实用函数全集
  • ADI硬件笔试面试题型解析上
  • DevEco Studio的使用
  • VUE组件库开发 八股
  • 时态--10--被动语态
  • Selenium 中 JavaScript 点击操作的原理及应用
  • Java:跨越时代的编程语言,持续引领技术革新
  • IPython 使用技巧整理
  • 强化学习鱼书(10)——更多深度强化学习的算法
  • Spring AI 项目实战(一):Spring AI 核心模块入门
  • 【Linux】Linux 进程基础
  • 华为港城 RAG 推理训练新突破:过程监督助力 5k 样本性能超越 90k 模型
  • 神经符号集成-三篇综述
  • COMSOL多边形骨料堆积混凝土水化热传热模拟
  • shell脚本总结13:head -c 和cut -c的区别
  • C++ 中的依赖注入(Dependency Injection)
  • Lua和JS的继承原理
  • 【PhysUnits】15.12 去Typenum库的SI 单位制词头实现(prefix.rs)
  • pycharm如何查看git历史版本变更信息
  • AI地面垃圾检测算法智能分析网关V4打造城市/公园/校园等场景环保卫生监管解决方案
  • MySQL 日志数据同步的详细教程
  • Message=“HalconDotNet.HHandleBase”的类型初始值设定项引发异常
  • JS手写代码篇---手写call函数
  • ADC接口电路设计详解
  • 动态规划-647.回文子串-力扣(LeetCode)
  • Double/Debiased Machine Learning
  • 同余的概念和基本性质
  • cursor对话
  • DPDK与网络协议栈