2020 年,在 Windows 7、IDEA 2018.3 和 64 位 JDK 8u171 环境中,运行 JUnit 反复失败。机器有约 8 GB 物理内存,任务管理器显示仍有可用内存,因此一开始没把系统内存限制当成主要方向。
错误报告提供了更具体的信息
关键摘要为:
There is insufficient memory for the Java Runtime Environment to continue.
Native memory allocation (malloc) failed to allocate
1745136 bytes for Chunk::new
Java HotSpot(TM) 64-Bit Server VM
这不是常见的 Java heap space。报告显示失败发生在 JVM 本地内存分配,相关线程为 C2 编译线程;进程还需要线程栈、元数据、代码缓存和其他本地区域。
不能因为报错发生在运行 JUnit 时,就只修改 IDEA 自身的堆参数。IDE 与它启动的测试 JVM 是两个进程。
为什么物理内存百分比不够用
Windows 的系统提交量与提交上限也是重要约束。分页文件能够扩展提交容量;即使物理内存图表没有接近 100%,分配仍可能因系统提交限制失败。Microsoft 分页文件与提交量说明
当时报告中物理内存仍有余量,但 swap 对应的可用数值已很小。继续查看配置发现分页文件约 1 GB,调整后测试恢复;当时采用的约 10 GB 是那台机器的历史值,不是通用推荐。
应该核对哪些数据
先保存脱敏的 JVM 错误报告,确认实际 Java 版本、位数、失败字节数、线程和生效 VM 参数。再查看系统提交量/上限、分页文件状态和磁盘可用空间,而不只看内存占用百分比。
同时记录 Xms、Xmx、线程数与测试并发。增大 Xmx 可能挤压本地内存余量;Code Cache 也有自己的用途,不能看到内存错误就把所有容量一起调大。
调整分页文件要有依据
确认属于提交空间不足后,在系统高级设置的性能与虚拟内存入口查看当前管理方式。按实际 Windows 版本、磁盘和负载选择系统管理或合理配置,保存旧值并按提示安排重启。
如果存在失控线程或本地内存泄漏,扩大分页文件只能推迟失败。修改后用相同测试负载观察提交峰值与稳定性,不能只以一次启动成功结束排查。