Java堆+非堆的总数(到目前为止)*未*超过512MB,但是内存使用量> 512MB导致R14错误

时间:2018-10-18 11:05:42

标签: java heroku memory

查看Heroku上的堆和非堆内存使用情况以及总内存消耗,我看到了意外的结果。

堆内存使用量约为175MB 非堆内存使用量约为125MB 总内存使用量:525MB

当总内存使用量超过512MB时,出现R14错误,内存使用率> 100%(102.8%)。

这是预期的吗?

编辑

我没有使用自定义Procfile,Heroku仪表板显示以下命令以用于启动dyno:web java -Dserver.port=$PORT $JAVA_OPTS -jar build/libs/*.jar

它使用的是JDK 11,没有任何特定的GC设置。

enter image description here

编辑2

添加了总内存使用情况图。 整个图形应用程序的注意事项是“空闲”,除了从我的站点发出的少量请求外,没有人在使用它。

在没有特定内存设置的情况下(使用Heroku默认设置),使用525MB。 将内存设置更改为-Xmx256m时,内存使用量将立即降至400 MB。 将其更改为-Xmx272m时,内存最多可达到500MB。

enter image description here

1 个答案:

答案 0 :(得分:0)

已使用的175MB的 堆仅代表JVM在总堆中使用的部分。如果使用默认值,则已提交的堆可能约为300MB(不幸的是,这在Heroku仪表板中未显示)。

额外的内存将来自以下内容:

  • 非堆(元空间,代码缓存等)
  • 线程(每个线程都有自己的堆栈并消耗内存)
  • JNI(非JVM管理的本地内存,请参见this blog
  • 外部进程(如果JVM启动任何其他JVM或非JVM进程,它将反映在总的动态内存中)

我建议以下内容:

  • 减小堆大小(256MB可能足够)
  • 降低其他一些默认设置(-XX:ReservedCodeCacheSize=50m -XX:MaxMetaspaceSize=80m
  • 减小任何线程池的大小(Tomcat?)

最后,在某些情况下,即使JVM是用它们完成的,许多临时直接内存映射仍与该进程相关联(即,操作系统不回收它们并将它们交换到磁盘上)。如果您没有看到任何不利的性能影响,则可能是这种情况。当有很多IO(例如解析大量的XML或JSON文件或生成PDF)时,就会发生这种情况。