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

相关文章:

  • RabbitMQ概念与管理端配置说明
  • 学习游戏制作记录(改进剑投掷状态)7.28
  • 四、计算机组成原理——第7章:输入/输出系统
  • Unity_UI_NGUI_组合控件2
  • 数论1.01
  • socketpair函数详解
  • MCU+RTOS调试
  • STM32-基本定时器
  • JavaScript手录-排序算法篇
  • 二分查找的「左右为难」:如何优雅地找到数组中元素的首尾位置
  • 城阳区奥赛暑假公益班第三次入门组初赛模拟赛
  • 把振动数据转成音频并播放
  • 提取apk中的各种语言翻译成表格,python脚本
  • Lakehouse: Unifying DW Advanced Analytics in Open Platforms
  • 《Java 程序设计》第 8 章 - Java 常用核心类详解
  • 未授权访问漏洞 总结
  • 阿里云【免费试用】Elasticsearch 智能运维 AI 助手
  • python毕业设计案例:基于python django的抖音数据分析与可视化系统,可视化有echarts,算法包括lstm+朴素贝叶斯算法
  • Flutter渲染引擎:Impeller和Skia
  • 低成本嵌入式Linux开发方案:通过配置文件实现参数设置
  • R语言与作物模型(以DSSAT模型为例)融合应用高级实战技术
  • 亚远景-“过度保守”还是“激进创新”?ISO/PAS 8800的99.9%安全阈值之争
  • 11.Dockerfile简介
  • 神经网络CNN、RNN、Transform
  • Avalonia的自定义边框窗口
  • opencv 模块裁剪 按需安装指定模块
  • 火线、零线、地线
  • ICPC 2024 网络赛(I)
  • 网络与信息安全有哪些岗位:(3)安全运维工程师
  • C++算法实例精讲