【发布时间】:2018-05-27 05:50:47
【问题描述】:
我已使用以下 vm 选项将 java 应用程序部署到 Heroku:
-Xmx300m -Xss512k -XX:MetaspaceSize=100M
尽管如此,我的应用程序始终从 Heroku 收到 Error R14 (Memory Quota Exceeded) 错误。这是因为内存占用达到540+mb(配额为512mb)。
当我在 VM args 中只为它分配 400mb 时,java 应用程序如何占用超过 500mb?我是否缺少 VM arg?
我预计 JVM 在达到 512mb 内存之前会 OOM(但它只会增加超出我设置的限制)。
也许我完全误解了这些 VM 参数的工作原理?
对此的任何帮助将不胜感激。
注意事项:
- 我正在使用 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
【问题讨论】:
-
您的应用程序本身可能存在内存泄漏,您可以在本地部署您的应用程序,并在 visualVM 或 Jconsole 中查看内存分配行为。
-
嗨@kakurala。如果发生内存泄漏,JVM OOM 会不会超过它的极限?
-
这里的关键是
measure.mem.jvm.nonheap.used=129M,这意味着有129MB的堆外内存正在使用,不关心堆限制。堆外内存可以被直接ByteBuffers、内存映射文件等使用。 heroku 是否认为配额包括 JVM 除了应用程序之外正在使用的内存,还是仅包括应用程序? -
除了 Java Heap 和 Metaspace 之外,还有很多东西可以使用内存:代码缓存、Direct ByteBuffers、线程堆栈、本机库...
-
代码缓存和元空间是完全不同的区域。 -Xss 是每个线程的限制,即更多线程 => 更多内存。使用Native Memory Tracking 获取有关 JVM 内存使用情况的详细报告(但仍不包括内存映射文件和本机库)。