You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用ArrayList::new时触发意外OOM错误,原因何在?

分析OutOfMemoryError的原因

哇,这个问题有点反直觉啊——按道理说你代码里创建的所有对象加起来占用的内存才几MB,16GB内存的机器完全不可能触发OOM。让我仔细拆解一下可能的问题点:

先算一笔内存账(以64位JVM开启指针压缩为例)

  • 50000个ListObject:每个对象包含2个int字段+对象头,总占用约24字节/个,总计≈1.2MB
  • HashMap中的50000个entry:每个HashMap.Node包含hash值、key引用、value引用、next引用,总占用约32字节/个,总计≈1.6MB
  • 50000个空ArrayList:每个空ArrayList包含对象头、数组引用、size字段,总占用约24字节/个,总计≈1.2MB
  • 自动装箱生成的Integer对象:因为你的key范围是0-99999,超过了Integer缓存池(-128~127),每个key都会生成新Integer,每个约16字节,总计≈800KB

所有对象加起来才不到5MB,完全不可能让16GB内存的机器OOM。那问题肯定出在其他地方:

可能的原因

  • JVM堆内存设置过小:默认情况下JVM不会把全部物理内存分配给堆,比如64位JDK默认堆最大值是物理内存的1/4(也就是4GB),但如果你的环境被修改过默认参数,或者手动设置了很小的-Xmx值(比如-Xmx128M),就可能触发OOM。
  • 机器内存被其他进程抢占:如果你的机器上同时运行了其他占用大量内存的程序(比如大型数据库、虚拟机),导致剩余可用内存不足以让JVM分配堆空间,也会出现OOM。
  • 代码存在笔误或实际实现不符:
    • 你写的count是50000,但实际运行的代码里可能是更大的数值(比如500万或5000万);
    • 你提供的ListObject是用int存key/value,但实际代码里可能是大对象(比如长字符串、大数组),导致每个ListObject占用大量内存。
  • 罕见的JDK版本bug:某些非常旧的JDK版本中,HashMap或computeIfAbsent的实现可能存在内存泄漏,但这种情况概率极低,JDK 8及以后的版本已经修复了大部分这类问题。

解决建议

  1. 手动设置JVM堆内存参数:启动程序时添加-Xmx8G(或更大的值,比如-Xmx12G),强制分配足够的堆内存。
  2. 检查机器内存使用情况:打开任务管理器(Windows)或top命令(Linux),看看是否有其他进程占用了大量内存,关闭不必要的进程释放资源。
  3. 核对代码一致性:确认运行的代码和你提供的完全一致,特别是count的值和ListObject的字段类型。
  4. 用内存分析工具定位问题:使用VisualVM、MAT等工具dump堆内存快照,查看到底是哪些对象占用了大量内存,这是最直接的排查方法。

内容的提问来源于stack exchange,提问作者Joker

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 09:05:53