当前位置: 首页 > 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.lqws.cn/news/91855.html

相关文章:

  • Flink 失败重试策略 :restart-strategy.type
  • React 第五十一节 Router中useOutletContext的使用详解及注意事项
  • NVIDIA DOCA 3.0:引领AI基础设施革命的引擎简析
  • 【Elasticsearch】search_after不支持随机到哪一页,只能用于上一页或下一页的场景
  • RAG优化知识库检索(5):多阶段检索与重排序
  • 苹果Mac系统如何彻底清理vscode插件Augment
  • 互联网大厂智能体平台体验笔记字节扣子罗盘、阿里云百炼、百度千帆 、腾讯元器、TI-ONE平台、云智能体开发平台
  • GLIDE论文阅读笔记与DDPM(Diffusion model)的原理推导
  • [特殊字符] Unity 性能优化终极指南 — Text / TextMeshPro 组件篇
  • 车载软件架构 --- 软件定义汽车开发模式思考
  • ABAP设计模式之---“高内聚,低耦合(High Cohesion Low Coupling)”
  • Java垃圾回收机制深度解析:从理论到实践的全方位指南
  • 项目课题——基于ESP32的智能插座
  • iOS 应用如何防止源码与资源被轻易还原?多维度混淆策略与实战工具盘点(含 Ipa Guard)
  • 云服务器部署Gin+gorm 项目 demo
  • Mac版本Android Studio配置LeetCode插件
  • 基于InternLM的情感调节大师FunGPT
  • 谷歌地图免费下载手机版
  • GPTBots在AI大语言模型应用中敏感数据匿名化探索和实践
  • Rust 函数
  • 15个基于场景的 DevOps 面试问题及答案
  • Celery 核心概念详解及示例
  • SpringBoot 系列之集成 RabbitMQ 实现高效流量控制
  • Vue 树状结构控件
  • 【Mysql】隐式转换造成索引失效
  • PopupImageMenuItem 无响应
  • 【AI教我写网站-ECG datacenter】
  • HDFS 写入和读取流程
  • 大模型模型推理的成本过高,如何进行量化或蒸馏优化
  • redis的哨兵模式和Redis cluster