我从第三方应用程序(logstash、fwiw)看到了此异常消息
java.lang.OutOfMemoryError: Java heap space: failed reallocation of scalar replaced objects
关于 OutOfMemoryError 的这种特定变体似乎没有很多信息,我想知道除了明显的“使用更少的堆”/“分配更多的堆”之外,是否有任何值得了解的关于如何响应这种变体的信息”.
Logstash 当时正在处理过多的 TRACE 输出(每毫秒大约 10 个 JSON 格式的事件),并且故意限制了堆,显然我们会考虑增加。
JDK
--version
输出是:
openjdk 11.0.23 2024-04-16 LTS
OpenJDK Runtime Environment Corretto-11.0.23.9.1 (build 11.0.23+9-LTS)
OpenJDK 64-Bit Server VM Corretto-11.0.23.9.1 (build 11.0.23+9-LTS, mixed mode)
但是...“标量替换对象重新分配失败”到底是什么意思?当 JVM 抛出这个特定异常时,内部发生了什么?
使用
git clone https://github.com/openjdk/jdk.git
,搜索错误消息并稍微跟踪使用站点,最终会出现“去优化”。
src/hotspot/share/runtime/deoptimization.cpp
其中写着类似
先前消除的对象的实际重新分配发生在 realloc_objects 中,...
另一个提示来自 wiki.openjdk.org,它说:
去优化是将优化的堆栈帧更改为未优化的堆栈帧的过程
综合起来,我认为在优化期间,对象可能会从堆移动到堆栈或以其他方式“消除”。因此,当“优化的堆栈帧”被取消优化时,对象需要堆上的空间。
因此,正如OP所建议的那样,“使用更少的堆”/“分配更多的堆”看起来是改善这种情况的唯一方法。