我最近更新了一个Play v1应用程序,以便在Heroku上使用OpenJDK v1.8,并且发现在典型加载后我开始相对较快地获得R14 errors - 物理内存已超过512MB限制并且现在正在交换影响性能。我需要经常重启应用程序以停止R14错误。该应用程序是一个非常典型的Web应用程序,我希望它能够在内存限制内轻松运行。
以下是NewRelic的屏幕截图,显示了超出的物理内存。我真的没有59个JVM,只是重启的结果。
我不太明白为什么“旧堆”似乎会影响“物理内存”,因为它没有接近“承诺堆”,为什么“物理内存”似乎更接近“使用堆“而不是”已提交的堆“
我已经使用Eclipse Memory Analyzer来分析一些堆转储,而Leak Suspects报告提到play.Play和play.mvc.Router作为嫌疑人虽然我不确定是否预期和/或他们是否与超出的物理内存直接相关。
有关详细信息,请参阅MAT生成的内容。
任何有关如何解决此问题的指导都会很棒。我正在使用Oracle Java 1.8在OS X上开发,并且还无法在本地复制确切的Heroku dyno环境(例如Ubuntu,OpenJDK 1.8)以尝试重现该问题。
更新2014年11月12日:
以下是Heroku支持的回复:
播放,然后依次为Netty分配IO的直接内存ByteBuffer对象。因为它们使用直接内存,所以JVM不会报告它们(Netty 4.x现在使用ByteBuf对象,它使用堆内存)。
你的应用程序使用的65MB匿名地图并不是非常罕见(我见过有人使用100 + mb)。一些解决方案包括:
如果这些解决方案不适合您,或者在采用这些解决方案后仍然遇到问题,请告诉我们。
如果您想在本地重现Heroku环境,我建议您安装Docker,并将此Docker image与您的应用程序一起使用。如果您对此有任何疑问,请告诉我们。