【问题标题】:Java Heap + Non-Heap total *not* exceeding 512MB by far, but memory usage > 512MB causing R14 errorsJava Heap + Non-Heap 总计 *不* 到目前为止超过 512MB,但内存使用量 > 512MB 导致 R14 错误
【发布时间】:2018-10-18 11:05:41
【问题描述】:

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

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

由于总内存使用量超过 512MB,我收到 R14 错误并且内存使用率 > 100% (102.8%)。

这是预期的吗?

编辑

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

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

编辑 2

添加了总内存使用图。 整个图形应用程序的注意事项是“空闲”,除了来自我网站的一些最少请求之外,没有人使用它。

没有特定的内存设置(使用 Heroku 默认值)使用 525MB。 将内存设置更改为 -Xmx256m 内存使用量立即降至 400 MB。 将其更改为 -Xmx272m 内存将达到 500MB。

【问题讨论】:

  • 您使用的是什么版本的 Java,您有哪些 GC 设置?如果您使用的是默认 GC 设置,请注明。
  • 请注意,JVM 统计数据并不包括进程使用的所有内存。非堆通常意味着堆栈、字符串池、反射数据等(都与 Java 直接相关),但不是本机代码单独使用的内存(可能是 JVM 内部、文件句柄、dll 库等)
  • 另外:“堆内存使用量约为 175MB”是指为堆保留 175MB 还是实际使用了 175MB(即填充了对象)?
  • 我更新了关于 JDK 版本、GC 和启动命令的问题。希望有帮助。我认为托马斯的最后一个问题确实很有趣。也许 Heroku 指标仪表板只显示实际使用的内容,而不是保留的内容。不幸的是,我没有这样的 Heroku 经验。
  • 我还添加了 Heroku 指标页面的屏幕截图。

标签: java heroku memory


【解决方案1】:

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

额外的内存将来自以下:

  • 非堆(元空间、代码缓存、其他一些东西)
  • 线程(每个线程都有自己的堆栈和消耗的内存)
  • JNI(本机内存不受 JVM 管理,请参阅 this blog)
  • 外部进程(如果 JVM 启动任何其他 JVM 或非 JVM 进程,它将反映在总 dyno 内存中)

我推荐以下:

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

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

【讨论】:

  • 感谢@codefinger,设置-Xmx256m(如果我阅读文档,默认为300)将总内存使用量从525MB恢复到大约。立即 400MB... 很有趣...
  • 将其从 -Xmx256m 更改为 -Xmx272 并将总使用内存从 400MB 更改为 500 MB...
  • 我在 EDIT2 下添加了另一个指标截图。
  • 顺便说一句,超过 512MB 是因为我今天早上启用了 JVM 运行时指标。我认为这会导致应用程序需要超过 512MB 的开销。似乎 Heroku 默认设置 (-Xmx300m) 一切都是平衡的,所以它只保持在 512MB 以下。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-03-25
  • 2018-05-27
  • 2010-12-08
  • 2016-03-17
  • 1970-01-01
  • 2015-10-20
  • 1970-01-01
相关资源
最近更新 更多