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

JVM 内存共享区域详解

Java 虚拟机在执行 Java 程序时,会将所管理的内存划分为若干个不同的数据区域。其中,堆(Heap)方法区(Method Area)所有线程共享的区域,属于 JVM 的共享内存区。


一、JVM 内存结构总览

区域名称是否线程共享说明
程序计数器(Program Counter Register)当前线程执行字节码的行号指示器
Java 虚拟机栈(JVM Stack)每个线程私有,方法调用栈帧
本地方法栈(Native Method Stack)用于调用 Native 方法
Java 堆(Heap)所有线程共享,用于存放对象实例
方法区(Method Area)所有线程共享,存储类结构、静态变量、运行时常量池等
运行时常量池(Runtime Constant Pool)方法区的一部分,存储编译时生成的常量和符号引用
直接内存(Direct Memory)特殊不在堆中,使用 JNI 分配的本地内存

二、JVM 共享内存区域有哪些?

1. Java 堆(Heap)

  • 作用:Java 堆是 JVM 中最大的一块内存区域,用于存储对象实例和数组,是垃圾收集器管理的主要区域。

  • 线程共享:是

  • 创建时机:在 JVM 启动时创建。

  • 内存划分

    • 新生代(Young Generation)

      • Eden 区:新对象优先在这里分配。
      • Survivor 区(S0 和 S1):用作对象复制回收。
    • 老年代(Old Generation)

      • 存放生命周期较长的对象。
    • (JDK 1.7 以前)永久代(PermGen)

    • (JDK 1.8 以后)元空间(Metaspace):使用本地内存替代永久代。

新生代对象分配与晋升过程
  • 对象先分配到 Eden 区。
  • 经一次 Minor GC 后存活的对象转移至 Survivor 区。
  • 如果在 Survivor 区多次存活(年龄达阈值如 15),将晋升到老年代。

2. 方法区(Method Area)→ 元空间(Metaspace)

  • 作用:用于存储已被虚拟机加载的类信息、常量、静态变量、JIT 编译后的代码等。

  • 线程共享: 是

  • JDK 变化

    • JDK 1.7 之前方法区由永久代实现。
    • JDK 1.8 开始使用 元空间(Metaspace) 替代,分配在本地内存中。
方法区存储内容包括:
  • 类结构信息(字段、方法、访问修饰符等)
  • 运行时常量池(Runtime Constant Pool)
  • 静态变量
  • 类初始化信息
  • JIT 编译后的代码缓存等

3. 运行时常量池(Runtime Constant Pool)

  • 所属区域:方法区的一部分

  • 线程共享: 是

  • 内容

    • 编译时生成的字面量(如字符串、整型常量等)
    • 符号引用(类名、方法名等)

4. 字符串常量池(String Constant Pool)

  • 位置

    • JDK 1.6 及以前:在永久代
    • JDK 1.7 起:转移至堆中
  • 目的:避免重复创建相同字符串,提升效率与节省内存

示例
String a = "ab";
String b = "ab";
System.out.println(a == b); // true,共享常量池引用
字符串常量池为何从永久代迁移到堆?
  • 永久代 GC 频率低,字符串长时间不回收。
  • 堆空间更大、GC 更灵活,能提升字符串内存回收效率。

5. 直接内存(Direct Memory)

  • 作用:通过 ByteBuffer.allocateDirect() 分配的内存,常用于性能敏感的 I/O 操作。

  • 使用方式:通过 JNI 方式直接使用本地内存。

  • 特点

    • 不属于 JVM 规范定义的内存区域。
    • 不是堆内存,也不在方法区。
    • 容易出现 OOM 错误(如未手动释放)。

三、JVM 非共享内存区域(仅作对比)

区域线程共享用途
程序计数器记录当前线程执行的位置(字节码行号)
虚拟机栈方法调用、局部变量、操作数栈等
本地方法栈执行 native 方法

面试高频考点总结

问题要点
JVM 哪些区域是线程共享的?Java 堆、方法区(元空间)、运行时常量池、字符串常量池
方法区和堆的区别?方法区存储类结构信息,堆存储对象实例;两者都线程共享
JDK 1.7/1.8 的内存结构变化?移除永久代,引入元空间;字符串常量池移动到堆
什么是直接内存?不在堆、不在方法区,用 JNI 访问的本地内存
方法区中存储的内容有哪些?类元数据、静态变量、常量池、JIT 编译代码等
http://www.dtcms.com/a/302289.html

相关文章:

  • Uniswap V2 成功上线 PolkaVM:Polkadot Hub 的里程碑时刻
  • 5190 - 提高:DFS序和欧拉序:树上操作(区域修改1)
  • 28天0基础前端工程师完成Flask接口编写
  • Ethereum:Geth运维实战,geth export与geth import命令的实用性深度评估
  • 【C++】手搓一个STL风格的vector容器
  • 【华为机试】210. 课程表 II
  • Kernel PWN 入门(二)
  • 【深度学习优化算法】10:Adam算法
  • Mybatis_4
  • 设计模式十二:门面模式 (FaçadePattern)
  • Kafka——请求是怎么被处理的?
  • 6.2 总线事务和定时 (答案见原书 P295)
  • 疏老师-python训练营-Day28类的定义和方法
  • 【LeetCode 热题 100】35. 搜索插入位置——二分查找(闭区间)
  • 区块链分叉原理与代码仿真
  • leetcode 2044. 统计按位或能得到最大值的子集数目 中等
  • 主要分布于内侧内嗅皮层的层Ⅲ的网格-速度联合细胞(Grid × Speed Conjunctive Cells)对NLP中的深层语义分析的积极影响和启示
  • 热斑漏检率↓78%!陌讯多模态算法在无人机光伏巡检的轻量化实践
  • 问题大全【1】
  • 【深度解析】R语言与作物模型(以DSSAT模型为例)融合应用
  • 散点图(散点矩阵)相关介绍
  • 【计算机科学与应用】基于多域变换的视频水印嵌入算法研究
  • 电脑出现英文字母开不了机怎么办 原因与修复方法
  • 开发笔记 | 实现人物立绘的差分效果
  • 达梦有多少个模式
  • 低成本嵌入式Linux开发方案:通过配置文件实现参数设置
  • LeetCode 68:文本左右对齐
  • 如何解决pip安装报错ModuleNotFoundError: No module named ‘papermill’问题
  • Docker搭建Hadoop集群
  • 进程管理(systemd)