信息发布→ 登录 注册 退出

在J*a里对象分配失败会发生什么_J*a堆扩容与GC触发策略解析

发布时间:2025-12-16

点击量:
J*a对象分配失败时,JVM先触发Minor GC,再尝试堆扩容(仅Parallel/Serial GC支持),均失败后才抛OutOfMemoryError;大对象、晋升失败、CMS并发模式失败等也会触发不同GC或OOM。

在java里对象分配失败会发生什么_java堆扩容与gc触发策略解析

当J*a对象分配失败时,JVM不会直接抛出OutOfMemoryError,而是先尝试自救:触发一次Minor GC,若仍无法腾出足够空间,再考虑扩容堆,扩容失败或扩容后仍分配不下,才会真正OOM。

对象分配失败的完整自救流程

J*a对象优先在Eden区分配,当Eden无足够连续空间时,并不立即报错:

  • 先检查是否启用了-XX:+UseSerialGC-XX:+UseParallelGC等策略,决定触发哪种GC
  • 执行Minor GC(年轻代回收),清理Eden和Survivor中不可达对象
  • 若GC后Eden仍有足够空间,分配继续;否则进入下一步
  • JVM判断是否可扩容堆(需满足MaxHeapSize未达上限,且操作系统允许)
  • 扩容成功后重试分配;扩容失败或分配仍失败,才抛出j*a.lang.OutOfMemoryError: J*a heap space

堆扩容不是无条件发生的

堆扩容受多层约束,不是“不够就扩”:

  • 仅当使用-XX:+UseParallelGC-XX:+UseSerialGC时,JVM才可能主动扩容;G1、ZGC、Shenandoah默认不主动扩容堆,更倾向触发GC或直接OOM
  • 扩容步长由-XX:HeapExpansionPercent(并行收集器)控制,默认5%,但每次最多扩-XX:MaxHeapFreeRatio设定的空闲比例上限
  • 底层依赖mmapVirtualAlloc系统调用,若OS内存不足或达到进程RLIMIT限制,扩容直接失败
  • 即使-Xms-Xmx设为相同值(如-Xms2g -Xmx2g),堆完全不可扩容,此时分配失败会跳过扩容环节,直奔GC→OOM

GC触发不只是看Eden满不满

除了Eden空间不足,还有多个隐式触发点会影响分配结果:

Project IDX Project IDX

Google推出的一个实验性的AI辅助开发平台

Project IDX 166 查看详情 Project IDX
  • 大对象直接进老年代:当对象大小超过-XX:PretenureSizeThreshold(默认0,即禁用),或大于Eden一半(Parallel GC下),会尝试在老年代分配;若老年代剩余空间不足,直接触发Full GC(或Mixed GC)
  • 晋升失败(Promotion Failure):Minor GC后,存活对象从Survivor复制到老年代时发现空间不够,触发Full GC;若Full GC后仍无法容纳,立即OOM
  • 并发模式失败(Concurrent Mode Failure):CMS在并发标记阶段,老年代被快速填满,被迫中断并发流程,降级为STW Full GC
  • 元空间/直接内存溢出不走此路径:这些属于堆外内存,失败时抛的是OutOfMemoryError: MetaspaceOutOfMemoryError: Direct buffer memory,与堆分配逻辑无关

如何定位是哪一环出了问题

开启关键JVM参数,让行为透明化:

  • -XX:+PrintGCDetails -XX:+PrintGCTimeStamps:看每次GC前后的各代容量、GC类型、耗时
  • -XX:+PrintAdaptiveSizePolicy(仅Parallel GC):观察JVM是否在动态调整Eden/Survivor比例或尝试扩容
  • -Xlog:gc*,gc+heap=debug(JDK 10+):更细粒度显示分配失败、扩容尝试、晋升决策等事件
  • 配合jstat -gc <pid></pid>实时查看堆各区域使用率变化趋势,判断是频繁Minor GC、老年代缓慢上涨,还是某次突增导致OOM

基本上就这些。分配失败不是终点,而是JVM启动的一连串自检动作的起点——理解它怎么救、为什么救不了,比死记“OOM就加内存”有用得多。

以上就是在J*a里对象分配失败会发生什么_J*a堆扩容与GC触发策略解析的详细内容,更多请关注其它相关文章!


相关文章: PHP教程:高效从URL路径中提取倒数第二个片段  Yandex免登录官网入口_俄罗斯Yandex搜索引擎直达链接  J*a初级项目如何接入API数据_第三方接口请求与响应解析  迅雷下载到U盘速度很慢怎么办_迅雷U盘下载慢优化方法  PHP表单提交消息延迟显示:Post-Redirect-Get模式深度解析与实践  修复二维数组索引越界异常:一维循环到二维坐标的正确映射  php源码怎么在电脑上测试_电脑测试php源码方法步骤【教程】  铁路12306卧铺选择攻略 铁路12306下铺座位预定技巧  知乎APP怎么管理已购盐选内容_知乎APP盐选内容购买记录与查看方法  1688商家版怎样分析买家画像精准供货_1688商家版分析买家画像精准供货【供货策略】  虚幻5科幻题材ARPG大作遭取消!本是《奇异人生》厂商新作  如何使 Jest 模拟函数默认抛出错误以提高测试效率  Lar*el如何正确地在控制器和模型之间分配逻辑_Lar*el代码职责分离与架构建议  腾讯视频怎么举报不良内容_腾讯视频内容举报流程与违规信息处理方法  PySpark中高效提取字符串右侧可变长度数字:使用regexp_extract  抖音小游戏合成大西瓜免费秒玩入口链接 抖音小游戏热门合集秒玩网站  优化Lar*el Docker镜像:Composer与PHP版本控制策略  c++如何使用Catch2编写单元测试_c++简洁易用的BDD风格测试框架  React列表渲染与独立状态管理:避免全局状态影响局部更新  文本文档写html代码怎么运行_文本文档html代码运行步骤【教程】  Golang如何实现Web接口签名验证_Golang Web接口签名校验开发方法  解决Python logging 中 datefmt 导致时间戳固定不变的问题  HTML长属性值处理:表单action路径优化与代码规范应对  Win10快速启动功能利弊分析 Win10开启或关闭快速启动教程【技巧】  J*a实现学校排课程序_面向对象结构化项目示例  在J*aScript中复现SciPy的B样条拟合与求值:关键考量  写好的html代码怎么运行出来_运行写好的html代码方法【教程】  电脑IP地址怎么查 查看本机IP地址的几种方法  Fabric Mod开发:在1.19.3+版本中正确添加自定义物品并管理物品组  AO3官网镜像链接 Archive of Our Own同人文在线浏览  TypeScript/J*aScript:高效查找数组中首个唯一ID对象  生成rdflib自定义SPARQL函数:参数匹配与实践指南  mysql密码锁定怎么解锁_mysql密码锁定解锁后修改密码步骤  163邮箱登录密码 163邮箱忘记密码找回  12306选座如何查看座位示意图_12306座位示意图解读与使用  word中如何让数字纵向排列_Word数字纵向排列方法  Google翻译怎么语音输入_Google翻译语音输入功能使用与设置方法  Shopware订单中获取产品自定义字段的实用指南  Python:递归比较文件夹内容并找出特定类型文件的差异  J*aScript中localStorage数据的获取、清洗与格式化教程  12306选座系统怎么选连座_12306选座多人连坐操作方法  解决 Express.js 中 PUT 请求密码修改失败的路由配置指南  冬*霸灯泡不亮怎么办_浴霸取暖灯一盏不亮的灯座清洁修复法  Python vgamepad库按键模拟:正确使用XUSB_BUTTON常量  c++中的std::forward_list和std::list有什么不同_c++ forward_list与list区别分析  漫蛙Manwa2官网入口地址分享 漫蛙漫画PC版永久访问通道  Win11 BitLocker密码忘了怎么办 Win11找回BitLocker恢复密钥方法【解决】  Web Components中自定义开关组件状态同步的常见陷阱与解决方案  J*aScript:在map操作中高效处理空数组  漫蛙漫画网页端入口 漫蛙2官方正版漫画站点 

在线客服
服务热线

服务热线

4008988990

微信咨询
二维码
返回顶部
×二维码

截屏,微信识别二维码

打开微信

微信号已复制,请打开微信添加咨询详情!