当前位置: 首页 > 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风险元空间溢出堆内存溢出

相关文章:

  • ​​食品电商突围战!品融电商全平台代运营,助您抢占天猫京东抖音红利!
  • Scrapy爬虫框架Spiders爬虫脚本使用技巧
  • Halcon光度立体法
  • Python训练第四十三天
  • DHCP 动态主机配置协议(Dynamic host configuration protocol)逐层封装过程: DHCP --> UDP --> IP
  • 相机Camera日志分析之二十四:高通相机Camx 基于预览1帧的process_capture_request三级日志分析详解
  • KITTI数据集(计算机视觉和自动驾驶领域)
  • Java编程之建造者模式
  • 项目课题——基于ESP32的智能插座
  • 24.【.NET8 实战--孢子记账--从单体到微服务--转向微服务】--单体转微服务--认证微服务
  • 英福康INFICON VGC501, VGC502, VGC503 单通道、双通道和三通道测量装置
  • AspectJ 在项目中的集成应用代码案例
  • VR教育:开启教育新时代的钥匙
  • Rhino插件大全下载指南:解锁犀牛潜能,提升设计效率
  • 基于大模型的慢性硬脑膜下血肿预测与诊疗系统技术方案
  • LabVIEW基于 DataSocket从 OPC 服务器读取数据
  • 【机器学习及深度学习】机器学习模型的误差:偏差、方差及噪声
  • HDFS 写入和读取流程
  • 40、响应处理-【源码分析】-基于请求参数的内容协商原理
  • Flink 失败重试策略 :restart-strategy.type
  • 有哪些做兼职的设计网站有哪些工作/西地那非片说明书
  • 企业网站的用户需求分析/竞价托管sem服务
  • 定制制作网站公司/疫情防控数据
  • 我做的网站有时打开很慢什么原因/关键词搜索排名公司
  • 做引流的公司是正规的吗/阜平网站seo
  • wordpress调用当前分类链接/广州网站优化运营