我们在Heroku上运行了一个JVM应用程序,它正在接收超出错误R14内存配额。
我们正在努力了解内存花费的位置,但这些数字并没有加起来。
在日志下方:
Process running mem=1174M(114.7%)
» 10:16:28.365 2015-01-21 09:16:28.099931+00:00 heroku web.1 - - Error R14 (Memory quota exceeded) Critical
» 10:16:43.322 2015-01-21 09:16:42.836517+00:00 app web.1 - - measure.mem.jvm.heap.used=272M measure.mem.jvm.heap.committed=546M measure.mem.jvm.heap.max=546M
» 10:16:43.322 2015-01-21 09:16:42.836583+00:00 app web.1 - - measure.mem.jvm.nonheap.used=106M measure.mem.jvm.nonheap.committed=107M measure.mem.jvm.nonheap.max=0M
» 10:16:43.322 2015-01-21 09:16:42.836644+00:00 app web.1 - - measure.threads.jvm.total=136 measure.threads.jvm.daemon=21 measure.threads.jvm.nondaemon=105 measure.threads.jvm.internal=10
» 10:16:43.322 2015-01-21 09:16:42.853114+00:00 app web.1 - - measure.mem.linux.vsz=2489M measure.mem.linux.rss=848M
Heroku报告1174M
正在使用中。 heroku-javaagent-1.4
会在其下方报告指标,这些指标加起来为546+107+136/2=721M
。剩下的1174-721=453M
可以用在哪里?我们怎么能继续排除故障?
考虑到我们的JVM选项,我在这里考虑了136个线程,每个线程有512K堆栈:
-javaagent:heroku-javaagent-1.4.jar=stdout=true,lxmem=true -Xms568m -Xmx568m -Xmn192m -Xss512k -XX:+UseCompressedOops
用于在1024x内存的2x dyno上运行。
由于
答案 0 :(得分:2)
这里有一些可能性。最有可能的是某些东西正在为某种IO分配本机内存映射。报告JVM内存使用情况的工具无法看到此信息。最常见的是,这是由Java NIO ByteBuffer对象发生的。这可以通过代码中的某些内容来完成,这可能表示应用程序中存在内存泄漏。或者它可以通过您的应用程序构建的框架/服务器来完成。
我发现Play框架和Jetty特别糟糕。在许多情况下,它们分配数百兆的本机内存。你在使用其中任何一种吗?我知道有人从Jetty转到Tomcat并解决了这个问题。
最终,如果额外的内存达到稳定状态,它可能没问题。这正是您的应用程序需要运行的内容。但是如果你发现它不断增长和增长,那么它可能表明存在内存泄漏。
我建议使用Heroku的支持提交一张票,他们可以使用smaps提供更多关于这个内存分配位置的信息。
完全披露:我为Heroku工作。