JVM——内存模型

1、程序计数器(Program Counter):

用于记录当前线程待执行的字节码指令位置 。若执行的是Native方法则计数器值为null 。是唯一一个不会触发OOM 的区域,生命周期与线程相同

  • 函数调用:当前PC值压入栈 ,PC更新为函数入口地址返回时函数地址弹出到PC地址
  • 循环/条件分支:直接跳转到对应的字节码指令位置
  • 多线程切换:涉及到各个线程PC的保存和恢复

2、虚拟机栈:

线程独享内存 ,每个方法在执行时都会创建一个栈帧,用于存储局部变量表、操作数栈、动态链接、方法出口等信息 ,可能会抛出StackOverflowError(栈过深,超出栈容量)和OOM异常。生命周期与线程相同

3、本地方法栈:

与虚拟机栈类似 ,但是为Native方法准备的栈,在HotSpot虚拟机中和虚拟机栈合二为一。也可能发生栈过深异常或OOM异常

4、堆(Heap):

JVM中最大的内存区域,被所有线程共享用于存放对象实例。 在虚拟机启动时创建,被划分为新生代和老年代,利于GC新生代又被分为Eden区和Survivor区。堆溢出时也会发生OOM异常。

5、方法区(元空间):

使用本地内存用于存储已被虚拟机加载的类信息、常量、静态变量、方法字节码、符号引用等数据。被称为堆的逻辑部分,可以不选择垃圾回收。内存不足抛出OOM异常。

  • 运行时常量池:方法区的一部分,用于存放编译期或运行时生成的各种字面量和符号引用。内存不足抛出OOM异常,jdk1.8后移入本地内存中的元数据区域,jdk1.7前位于堆内的永久代

6、直接内存:

不属于JVM运行时数据区的一部分,通过NIO类引入,是一种堆外内存,可显著提高IO性能。受本机总内存的限制。内存不足抛出OOM异常。

栈详解:

  • 栈中存储的是当前线程中的局部变量、操作数栈和方法调用信息,方法返回地址及以一些临时数据
  • 栈中一般存储的是对象的引用,指向堆中的对象实例
  • 每当有方法调用时都会创建一个栈帧,用于存储该方法的信息,方法执行完毕后对应栈帧也会移除
  • 栈的存取速度比堆快,使用的是简单的先进后出结构
  • 栈空间相对较小且固定,可能会发生栈溢出(递归过深或内存超限)
  • 栈中数据对于线程来说是私有的

堆详解:

  • 存储对象实例 ,数据的生命周期交由GC管理
  • 存储空间较大 ,但存取速度相对较慢
  • 所有线程共享数据

新生代:

分为Eden区Survivor区Eden区用于存放存活概率较低的对象 (如大多数新创建的对象),Eden区相对较小 ;Survivor区分为from区和to区 ,每次进行Minor GC后,Eden区存活的对象和form区存活的对象会移动到to区域,并增加它们的年龄。

Eden区满时 ,会触发Minor GC,将存活对象复制到幸存区或老年代,清空Eden区和from区

老年代:

存放长期存活的对象 ,存储空间一般是新生代的两倍 ,因此Major GC的发生频率较低

老年代空间不足(阈值默认45%)时 ,会触发对应回收器的回收(默认G1回收器),并发回收失败则触发full GC

大对象区:

某些回收器实现(如G1垃圾收集器),为大对象分配了专门的区域。大对象区域指需要大量连续空间的对象,例如大数组 。这类对象直接分配在老年代 ,以避免新生代频繁复制导致长时间STW

内存泄漏:

本质上是已经不再需要使用的对象仍然存在引用无法被回收导致可用内存逐渐减少

常见原因:
  • 静态集合使用静态数据结构 (HashMap或ArrayList),静态对象生命周期与JVM进程相同,存储对象且未在使用完后及时清理
  • 事件监听:未取消事件对事件源的监听,导致对象持续被引用
  • 会话或连接未及时关闭:例如数据库连接,流式处理的连接都会分配内存进行处理,若没有关闭也会造成内存泄漏。
  • 线程数据未释放 :未停止的线程持有对无用对象的引用 (例如ThreadLocal实例内部持有value的强引用,而key由于弱引用已被回收
相关推荐
木宇(记得热爱生活)11 分钟前
Qt GUI缓存实现
开发语言·qt·缓存
lly20240615 分钟前
C# 正则表达式
开发语言
Chef_Chen18 分钟前
从0开始学习R语言--Day58--竞争风险模型
android·开发语言·kotlin
minji...33 分钟前
数据结构 堆(4)---TOP-K问题
java·数据结构·算法
咖啡の猫41 分钟前
bash的特性-常见的快捷键
开发语言·chrome·bash
命苦的孩子42 分钟前
Java 中的排序算法详解
java·开发语言·排序算法
咖啡の猫42 分钟前
bash的特性-常用的通配符
开发语言·chrome·bash
凉冰不加冰1 小时前
JVM类加载机制全流程详解
jvm
Seven971 小时前
Spring AI 框架中如何集成 MCP?
java
开往19821 小时前
spring boot整合mybatis
java·spring boot·mybatis