尽管设置了-Xmx300m -Xss512k -XX,但Java内存超过512mb:MetaspaceSize = 100M?

时间:2017-12-13 10:57:56

标签: java heroku jvm

我使用以下vm选项向Heroku部署了一个java应用程序:

-Xmx300m -Xss512k -XX:MetaspaceSize=100M

尽管如此,我的应用程序始终从Heroku获得错误R14(超出内存配额)错误。这是因为内存占用量达到540 + mb (配额为512mb)。

当我只在VM args中为它分配400mb时,java应用程序如何占用超过500mb?我错过了一个VM arg吗?

我希望JVM在达到512mb内存之前达到OOM(但它只是超出了我设置的限制)。

也许我完全误解了这些虚拟机的工作原理?

对此的任何帮助都将非常感激。

注意:

  • 我正在使用java 8
  • 我的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 

2 个答案:

答案 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阈值。