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

尽管设置了-Xmx300m-Xss512k-XX:MetaspaceSize=100M,但Java内存仍超过512mb?,java,heroku,jvm,Java,Heroku,Jvm,我已使用以下vm选项将java应用程序部署到Heroku: -Xmx300m -Xss512k -XX:MetaspaceSize=100M 尽管如此,我的应用程序始终从Heroku收到错误R14(超过内存配额)错误。这是因为内存占用达到540+mb(配额为512mb) 当我在VM参数中只为java应用程序分配了400mb时,它怎么能占用超过500mb的空间呢?我是否缺少VM参数 我希望JVM在达到512mb的内存之前会停止运行(但它只是超出了我设置的限制) 也许我完全误解了那些VM参数是如何

我已使用以下vm选项将java应用程序部署到Heroku:

-Xmx300m -Xss512k -XX:MetaspaceSize=100M
尽管如此,我的应用程序始终从Heroku收到错误R14(超过内存配额)错误。这是因为内存占用达到540+mb(配额为512mb)

当我在VM参数中只为java应用程序分配了400mb时,它怎么能占用超过500mb的空间呢?我是否缺少VM参数

我希望JVM在达到512mb的内存之前会停止运行(但它只是超出了我设置的限制)

也许我完全误解了那些VM参数是如何工作的

在此方面的任何帮助都将不胜感激

注:

  • 我正在使用Java8
  • 我的文件如下:

    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 
当我在VM参数中只为java应用程序分配了400mb时,它怎么能占用超过500mb的空间呢?我是否缺少VM参数

JVM有许多种类的内存,包括堆、元空间、线程堆栈、代码缓存等等。甚至可以通过JNI分配JVM无法解释的内存。看一看

我希望JVM在达到512mb的内存之前会停止运行(但它只是超出了我设置的限制)

大多数OOM错误只有在堆空间用完时才会发生。在您的情况下,您有足够的堆空间,但所有其他类别的堆空间加起来都超过了512mb的限制

您可以尝试将
Xmx
降低到
-Xmx256m
。如果低于这个值,您可能会开始出现OOM错误

您可能还希望检查代码是否存在IO缓冲区泄漏。如果未正确关闭,它们有时会导致本机内存(堆外)泄漏。最后,检查您的依赖项(第三方库)是否正在使用JNI或分配本机内存

-Xmx256m -XX:+UseContainerSupport
当我在VM参数中只为java应用程序分配了400mb时,它怎么能占用超过500mb的空间呢?我是否缺少VM参数

JVM有许多种类的内存,包括堆、元空间、线程堆栈、代码缓存等等。甚至可以通过JNI分配JVM无法解释的内存。看一看

我希望JVM在达到512mb的内存之前会停止运行(但它只是超出了我设置的限制)

大多数OOM错误只有在堆空间用完时才会发生。在您的情况下,您有足够的堆空间,但所有其他类别的堆空间加起来都超过了512mb的限制

您可以尝试将
Xmx
降低到
-Xmx256m
。如果低于这个值,您可能会开始出现OOM错误

您可能还希望检查代码是否存在IO缓冲区泄漏。如果未正确关闭,它们有时会导致本机内存(堆外)泄漏。最后,检查您的依赖项(第三方库)是否正在使用JNI或分配本机内存

-Xmx256m -XX:+UseContainerSupport
是为我做的。使用Heroku默认值(即-Xmx300m)超过了Dyno的512MB阈值


是为我做的。使用Heroku默认值(即-Xmx300m)超过了动态的512MB阈值。

应用程序本身可能存在内存泄漏,您可以在本地部署应用程序,并在visualVM或Jconsole.hi@kakurala中查看内存分配行为。如果出现内存泄漏,JVM是否会OOM,而不仅仅是超出其限制?这里的关键是
measure.mem.JVM.nonheap.used=129M
,这意味着使用了129MB的堆外内存,这与堆限制无关。堆外内存可由直接
字节缓冲区
、内存映射文件等使用。HeloCu是否考虑了配额,包括JVM除了应用程序之外的内存,还是应用程序?除了java堆和Meta SPACE之外,还有更多的东西可以使用内存:代码缓存、直接字节缓冲区、线程栈、本地库…代码缓存和Meta SPACE是完全不同的区域。Xss是每个线程的限制,即更多线程=>更多内存。用于获取有关JVM内存使用情况的详细报告(但仍不包括内存映射文件和本机库)。应用程序本身可能存在内存泄漏,您可以在本地部署应用程序,并在visualVM或Jconsole.hi@kakurala中查看内存分配行为。如果出现内存泄漏,JVM是否会OOM,而不仅仅是超出其限制?这里的关键是
measure.mem.JVM.nonheap.used=129M
,这意味着使用了129MB的堆外内存,这与堆限制无关。堆外内存可由直接
字节缓冲区
、内存映射文件等使用。HeloCu是否考虑了配额,包括JVM除了应用程序之外的内存,还是应用程序?除了java堆和Meta SPACE之外,还有更多的东西可以使用内存:代码缓存、直接字节缓冲区、线程栈、本地库…代码缓存和Meta SPACE是完全不同的区域。Xss是每个线程的限制,即更多线程=>更多内存。用于获取有关JVM内存使用情况的详细报告(但仍不包括内存映射文件和本机库)。