我使用以下vm选项向Heroku部署了一个java应用程序:
-Xmx300m -Xss512k -XX:MetaspaceSize=100M
尽管如此,我的应用程序始终从Heroku获得错误R14(超出内存配额)错误。这是因为内存占用量达到540 + mb (配额为512mb)。
当我只在VM args中为它分配400mb时,java应用程序如何占用超过500mb?我错过了一个VM arg吗?
我希望JVM在达到512mb内存之前达到OOM(但它只是超出了我设置的限制)。
也许我完全误解了这些虚拟机的工作原理?
对此的任何帮助都将非常感激。
注意:
我的procfile如下:
web: java -Xmx300m -Xss512k -XX:MetaspaceSize=100M -javaagent:./lib/heroku-javaagent-2.0.jar=stdout=true,lxmem=true -Dserver.port=$PORT -Dspring.profiles.active=heroku -cp ./app.jar org.springframework.boot.loader.JarLauncher
上面的java代理在日志中吐出以下详细信息:
Dec 13 11:45:54 app/web.1: measure.mem.jvm.heap.used=177M measure.mem.jvm.heap.committed=212M measure.mem.jvm.heap.max=273M
Dec 13 11:45:54 app/web.1: measure.mem.jvm.nonheap.used=129M measure.mem.jvm.nonheap.committed=132M measure.mem.jvm.nonheap.max=0M
Dec 13 11:45:54 app/web.1: measure.mem.jvm.direct.used=0M measure.mem.jvm.direct.count=0 measure.mem.jvm.direct.capacity=74M
Dec 13 11:45:54 app/web.1: measure.mem.jvm.mapped.used=0M measure.mem.jvm.mapped.count=0 measure.mem.jvm.mapped.capacity=0M
Dec 13 11:45:54 app/web.1: measure.mem.linux.vsz=5817M measure.mem.linux.rss=543M
答案 0 :(得分:1)
当我只在VM args中为它分配400mb时,java应用程序如何占用超过500mb?我错过了一个VM arg吗?
JVM有许多类别的内存,包括堆,元空间,线程堆栈,代码缓存等。甚至可以通过JNI分配JVM无法解释的内存。看看this blog post on JVM memory。
我希望JVM在达到512mb内存之前达到OOM(但它只是超出了我设置的限制)。
大多数OOM错误仅在堆空间不足时发生。在您的情况下,您有足够的堆空间,但所有其他类别正在累计并运行您超过512mb的限制。
您可以尝试将Xmx
降低为-Xmx256m
。低于此值,您可能会开始收到OOM错误。
您可能还需要检查代码是否泄漏IO缓冲区。如果未正确关闭,它们有时会导致本机内存(堆外)泄漏。最后,检查您的任何依赖项(第三方库)是否正在使用JNI或分配本机内存。
答案 1 :(得分:0)
-Xmx256m -XX:+UseContainerSupport
是为我做的。使用Heroku默认值(即-Xmx300m)超过了Dyno的512MB阈值。