swisscom云代工厂春季启动应用程序内存不足

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了swisscom云代工厂春季启动应用程序内存不足相关的知识,希望对你有一定的参考价值。

我有一个只需要最多的SpringBoot应用程序。 284 MB内存。但我只能以最大值启动应用程序。 768 MB内存。即使我稍后减少内存,我总是会收到以下错误:

[APP/PROC/WEB/0] ERR Cannot calculate JVM memory configuration: There is insufficient memory remaining for heap. Memory limit 384M is
less than allocated memory 672509K (-XX:ReservedCodeCacheSize=240M, -XX:MaxDirectMemorySize=10M, -XX:MaxMetaspaceSize=109309K, -Xss1M * 300 threads)

我已经在cf中使用相同的应用程序没有这个问题。 cf中有什么变化?在2或3周之前,它仍然有效。

提前感谢您的快速回答!

答案

我已经在cf中使用相同的应用程序没有这个问题。 cf中有什么变化?在2或3周之前,它仍然有效。

您必须已升级到Java Build Pack v4。使用JBP v3,您可以推送具有较少内存量的应用程序,但是使用该版本的buildpack和小内存限制推送的应用程序也很容易崩溃。原因是因为当JBP进行计算时,JBP v3没有考虑JVM使用的所有内存区域,所以虽然它会让你的应用程序启动,但应用程序仍然可以在以后超过它的内存限制。 JBP v4计算内存的方式现在更加准确,并考虑了所有JVM的内存区域。

最终结果是,运行少于1G内存的JBP v4应用程序在暂存时会看到以下错误,运行512M或更少的应用程序几乎肯定会在暂存时看到此错误:

ERR Cannot calculate JVM memory configuration: There is insufficient memory remaining for XXXX

但是,成功执行的Java应用程序崩溃的可能性要小得多。

https://discuss.pivotal.io/hc/en-us/articles/115011717548-Insufficient-memory-when-using-Java-Buildpack-4-0-

那么这是否意味着您无法运行RAM少于1G的Java应用程序?不,你可以,但这需要一些调整。这里列出了一些你可以调整以节省一些内存的东西。

  • 线程数。 JBP假设您的应用程序将运行250个线程。这对于Web应用程序来说非常常见,对于Tomcat的内部资源,它将有大约50个,对于请求处理,它将有200个。您可以降低此值,但需要确保您的应用不会超过您设置的任意线程数,否则您的应用可能会崩溃。对你而言,这将通过Spring Boot调整Tomcat的配置。 JBP的较低线程数的示例: cf set-env my-application JBP_CONFIG_OPEN_JDK_JRE '{ memory_calculator: { stack_threads: 50 } }' Spring Boot application.properties中的较低线程数的问题: server.tomcat.max-threads=25 注意:这只是请求处理线程。 Tomcat本身有线程,你的应用也可以创建线程。您应该真正查看线程转储或JVisualVM以查看您的应用程序需要多少个线程(即测量,不要猜测)
  • 线程堆栈大小(-Xss)。这是传递给JVM的值,它控制每个线程需要多少内存。它默认为1M,这是非常高的。在大多数情况下,您可以安全地将其降低到160K,这是Java 8允许的最小值。如果您有250个线程并进行此更改,您将保存(1M * 250) - (160K - 250)= 211M的RAM 。 注意:如果您过多地降低线程堆栈大小,您将在应用程序中看到StackOverflow异常。如果发生这种情况,请保持冷静并提高价值,直到它们消失为止。
  • 降低保留代码缓存。这是JVM缓存JIT代码的地方。默认为240M。您可以降低此值,但请谨慎使用,因为这绝对会影响性能。你也可以看看errors at runtime if this value is not high enough。 同样,最好衡量一下您的应用需求而不是猜测。您应该能够使用JVM's NMT进行测量。
  • 您可以手动调整JVM使用的其他内存区域,如Heap&Metaspace。使用JBP v4,就像使用cf set-envmanifest.yml文件设置JAVA_OPTS环境变量一样简单。显然,如果你降低这些值,你需要注意不要太低,在这种情况下,你最终会得到OutOfMemoryErrors。 注意:如果您将一个区域设置为未设置,例如堆或元空间,JBP将使用手动自定义后剩余的任何内容巧妙地计算它。

希望有所帮助!

另一答案

我不是云代工厂中java应用程序内存处理方面的专家,但根据我的想法,我需要知道以下内容:

  • Java应用程序通常通过Java Buildpack部署。如果您没有在manifest.yml中定义一个版本,它将采用主分支。由于主分支一直在变化,我认为部署参数也可能会发生变化。
  • Java Build包使用Java Buildpack Memory Calculator来评估像-Xmx这样的JVM内存参数。您可以在manifest.yml中自己配置这些参数,但如果您想使用云代工厂的扩展功能,则不建议这样做。
  • 所以 - 当你定义你的云代工厂应用程序允许使用500MB内存并且构建包计算器评估更多时,它可能不起作用并导致一些错误。

您可以在清单中执行的操作是使用Memory计算器文档中提到的所有参数。例如,你可以给计算器一个提示,你需要更少的线程(例如memory_calculator: { stack_threads: 100}

当您使用“硬编码”某些内存参数时可以正常使用:这里是我的Spring Boot 2 / Java 9应用程序的示例manifest.yml,我使用的限制为400 MB。它适用于我,但可能不是立即复制的东西。这取决于您的应用程序。

applications:
- name: demo-app
  path: target/demo-app-1.0.0.jar
  instances: 1
  buildpack: https://github.com/cloudfoundry/java-buildpack.git
  memory: 400m
  env:
    JAVA_OPTS: '-XX:MaxMetaspaceSize=80780K -Xss512k -Xmx200M -XX:ReservedCodeCacheSize=16M -XX:MaxDirectMemorySize=16M'
    JBP_CONFIG_OPEN_JDK_JRE: '{ jre: { version: 9.+ } }'

以上是关于swisscom云代工厂春季启动应用程序内存不足的主要内容,如果未能解决你的问题,请参考以下文章

春季启动批处理到具有多个作业的春季云任务

阿里云云原生中间件春季实习招聘启动

云帮手在windows下提示虚拟内存不足,如何解决?

春季云流-消费者配置不起作用

阿里云已杀死问题

阿里云已杀死问题