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

JVM的内存划分

JVM(Java Virtual Machine)的内存划分主要包括以下几个运行时数据区域:

1. 程序计数器(Program Counter Register)

  • 作用:当前线程执行的字节码行号指示器。
  • 特点
    • 线程私有(每个线程独立拥有)。
    • 执行Java方法时记录字节码指令地址,执行Native方法时为空(Undefined)。
    • 唯一不会抛出OutOfMemoryError的区域。

2. 虚拟机栈(VM Stack)

  • 作用:存储方法执行的栈帧(局部变量表、操作数栈、动态链接、方法出口等)。
  • 特点
    • 线程私有,生命周期与线程相同。
    • 每个方法执行时创建栈帧,方法结束后栈帧销毁。
  • 异常
    • 栈深度超过限制时抛出StackOverflowError(如递归过深)。
    • 动态扩展失败时抛出OutOfMemoryError(如-Xss参数设置过小)。

3. 本地方法栈(Native Method Stack)

  • 作用:与虚拟机栈类似,但为Native方法服务(如Object.wait()等)。
  • 特点
    • 线程私有。
    • 不同JVM实现可能不同(如HotSpot将其与虚拟机栈合并)。
  • 异常:同虚拟机栈,可能抛出StackOverflowErrorOutOfMemoryError

4. 堆(Heap)

  • 作用:存储对象实例和数组,是垃圾回收的主要区域。
  • 特点
    • 线程共享,所有对象实例和数组都在此分配。
    • 可通过-Xms-Xmx参数调整大小。
  • 分区(以HotSpot为例)
    • 新生代(Young Generation)
      • Eden区:新对象初始分配的区域。
      • Survivor区(S0、S1):Eden区满时,存活对象被移至Survivor区。
    • 老年代(Old Generation):长期存活的对象进入老年代(如多次GC后仍存活的对象)。
    • 永久代/元空间(PermGen/Metaspace)
      • 永久代(Java 7及以前):存储类信息、常量池等,固定大小,可能导致OutOfMemoryError: PermGen space
      • 元空间(Java 8+):使用本地内存,默认无上限,避免了永久代的内存溢出问题。
  • 异常:堆内存不足时抛出OutOfMemoryError: Java heap space

5. 方法区(Method Area)

  • 作用:存储已被虚拟机加载的类信息、常量、静态变量等。
  • 特点
    • 线程共享。
    • 逻辑上属于堆的一部分,但HotSpot在Java 8后用元空间(本地内存)实现。
  • 运行时常量池(Runtime Constant Pool)
    • 方法区的一部分,存储编译期生成的常量和符号引用。
    • 支持运行时动态生成常量(如String.intern())。
  • 异常:元空间不足时抛出OutOfMemoryError: Metaspace

6. 直接内存(Direct Memory)

  • 作用:不属于JVM运行时数据区,使用UnsafeNIOByteBuffer.allocateDirect()直接分配堆外内存。
  • 特点
    • 不受堆大小限制,但受物理内存和-XX:MaxDirectMemorySize参数限制。
  • 异常:内存不足时抛出OutOfMemoryError

总结

区域线程私有存储内容常见异常
程序计数器字节码行号
虚拟机栈方法栈帧(局部变量、操作数栈等)StackOverflowError
本地方法栈Native方法栈帧StackOverflowError
对象实例、数组OutOfMemoryError: Heap Space
方法区(元空间)类信息、常量、静态变量OutOfMemoryError: Metaspace
直接内存堆外内存(NIO直接缓冲区)OutOfMemoryError

补充

  • 垃圾回收(GC):主要针对堆和方法区(元空间)。
  • JVM参数示例
    • -Xms2048m:堆初始大小2GB。
    • -Xmx2048m:堆最大大小2GB。
    • -XX:MetaspaceSize=256m:元空间初始大小256MB。
    • -XX:MaxDirectMemorySize=512m:直接内存最大512MB。
http://www.dtcms.com/a/200117.html

相关文章:

  • springboot+mybatis或mybatisplus在进行%name%的前后模糊查询时如何放防止sql注入
  • 封装一个基于 WangEditor 的富文本编辑器组件(Vue 3 + TypeScript 实战)
  • 4.【Linux】Linux工具(2)
  • Dolphinscheduler执行工作流失败,后台报duplicate key错误
  • 青岛地铁二号线列车运行图优化系统
  • ROS2简介
  • Spring boot 学习笔记2
  • DAY27
  • Java设计模式之外观模式:从入门到精通(保姆级教程)
  • 【学习笔记】机器学习(Machine Learning) | 第七章|神经网络(2)
  • TYUT-企业级开发教程-第5章
  • Python编程从入门到实践 PDF 高清版
  • vue2.0 组件
  • Java大厂面试三轮问答:微服务与数据库技术深度解析
  • matlab绘制光学传递函数mtf曲线
  • 精益数据分析(69/126):最小可行化产品(MVP)的设计、验证与数据驱动迭代
  • 第35周Zookkeeper+Dubbo 面试题精讲
  • 经典密码学和现代密码学的结构及其主要区别(1)凯撒密码——附py代码
  • k8s集成环境中pod运行的容器退出码141故障解决方案及排查方向,其他退出码也可以参考此篇
  • javaScript学习第三章(流程控制小练习)
  • Spring的后置处理器是干什么用的?扩展点又是什么?
  • Docker 核心原理详解:Namespaces 与 Cgroups 如何实现资源隔离与限制
  • React集成百度【JSAPI Three】教程(001):快速入门
  • Python----目标检测(labelimg和labelme的安装与使用,Pycharm配置教程)
  • 养生指南:解锁健康生活新方式
  • BGP综合实验
  • Nginx基础知识
  • java基础-关键字:static、单例模式
  • QPS与TPS区分及压测指标解读
  • 渗透测试核心技术:漏洞挖掘与利用