我们有一个JVM应用程序运行在Heroku上,它收到错误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
的其余部分可以用在哪里?我们如何继续进行故障排除?
我在这里考虑了136个线程,每个线程具有512K堆栈,给定JVM选项:
-javaagent:heroku-javaagent-1.4.jar=stdout=true,lxmem=true -Xms568m -Xmx568m -Xmn192m -Xss512k -XX:+UseCompressedOops
用于在1024M内存的2倍测力计上运行。
谢谢
2条答案
按热度按时间qkf9rpyu1#
这里有几种可能性。最有可能的是,某些东西正在为某种IO分配本地内存Map。报告JVM内存使用情况的工具无法看到这一点。最常见的情况是,Java NIO ByteBuffer对象会发生这种情况。这可能是由代码中的某些东西造成的,这可能表明应用中存在内存泄漏。也可能是由构建应用的框架/服务器造成的。
我发现Play framework和Jetty在这方面特别糟糕。在很多情况下,它们分配了数百兆字节的本地内存。你在使用这两个吗?我认识一些人,他们从Jetty切换到Tomcat并解决了这个问题。
最终,如果额外的内存达到稳定状态,可能是正常的。这正是你的应用程序运行所需要的。但如果你发现它一直在增长,那么它可能意味着内存泄漏。
我建议在Heroku的支持下提交一个票证,他们可以使用smap来提供更多关于内存分配位置的信息。
充分披露:我为Heroku工作
gcuhipw92#
这个问题确实存在了很长时间,但我最近遇到了同样的问题。
解决方案是为我的静态文件配置一个服务器。你可以为静态文件使用Nginx。
实际上,静态文件的加载通过I / O请求消耗内存。