首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Java构建包内存计算

Java构建包内存计算
EN

Stack Overflow用户
提问于 2022-03-10 14:02:48
回答 1查看 897关注 0票数 0

带有Spring应用程序的Java内存计算器在具有1GB内存的Docker容器中计算内存,正如它在文档中所述,它占用整个可用内存,这是计算JVM选项:

计算的JVM内存配置:-XX:MaxDirectMemorySize=10M -Xmx747490K -XX:MaxMetaspaceSize=157725K -Xss1M (总内存: 1G,线程数: 50,加载类计数: 25433,空间: 0%)

问题是,它为什么要占用整个可用内存并将其分配给JVM?它应该在JVM之外为java进程留出一些内存。这可能导致OOM,因为JVM认为它本身有1GB (堆为747490K),而实际上它的OOM较少,因为它的一些内存是由本机内存在JVM之外使用的。

我不应该自己使用这个计算器并设置JVM配置,或者我可以以某种方式重新配置它?

EN

回答 1

Stack Overflow用户

发布于 2022-03-11 15:00:39

的问题是,它为什么要占用整个可用内存并将其分配给JVM?

假设容器中运行的唯一东西是Java应用程序,因此它分配要使用的所有可用内存。

如果您在容器中执行shell并运行其他进程或运行其他进程,您需要告诉内存计算器,这样它就可以考虑到这一点。

这可能导致OOM,因为JVM认为自己有1GB (堆为747490K),而在现实中,它的内存更少,因为它的一些内存被本机内存在JVM之外使用。

内存计算器考虑到Java进程中的主要内存区域。不只是堆。也就是说,它不能100%保证你永远不会超过你的记忆限制。用Java应用程序是不可能的。

作为应用程序开发人员,您可以做一些事情,比如创建10,000个线程或JNI,这些都是无法限制的,而且可能占用大量内存。如果您这样做,您的应用程序将超过其容器内存限制和崩溃。

内存计算器试图为大多数常见的Java工作负载提供合理的内存配置。运行一个web应用程序,运行一个微服务,运行一些批处理作业等等.

如果你正在做一些不符合这个模式的事情,那么你可以简单地告诉内存计算器,它会相应地调整事情。

我不应该使用这个计算器并自行设置JVM配置,或者我可以以某种方式重新配置它?

即使您需要自定义计算器正在进行的操作,它也会很有帮助。手动计算这些值是额外的工作,特别是在更改内存限制非常容易的情况下。如果您的ops团队增加了容器的内存限制,您希望应用程序能够自动调整到该配置(以及它可以)。

除此之外,内存计算器还善于早期发现问题。如果您手动配置JVM,并将它搞砸了,假设您分配了过多的内存,那么JVM在尝试获得更多内存而不能获得更多内存之前,不一定会在意。在未来的某个时候,您将遇到问题,但还不清楚什么时候(可能在Sat,lol的凌晨3点)。

使用内存计算器,当容器第一次开始确保内存设置正常时,它就会进行计算。如果配置有问题,就会失败,并通知您。

提示:

  1. 您可以通过简单地在JAVA_TOOL_OPTIONS env变量中设置JAVA_TOOL_OPTIONS选项来覆盖内存计算器定义的值。例如,如果我想允许更直接的内存,我会设置JAVA_TOOL_OPTIONS='-XX:MaxDirectMemorySize=50M'。然后,当您重新启动容器时,内存计算器将移动内存以容纳它。

  1. ,你不想设置的一件事是-Xmx。内存计算器应该始终设置这一点,因为它会将其设置为在其他区域计算完毕后所剩的任何内容。你可以把它想象成HEAP = CONTAINER_MEMORY_LIMIT - (all static memory regions)

如果要设置-Xmx,就必须完全正确。如果太低,那你就是在浪费记忆。如果它太高,那么您可能会超过容器内存限制,从而导致崩溃。

简而言之,如果您认为要设置-Xmx,则应该增加容器内存限制或减少一个静态内存区域。

如果在容器中运行其他内容,则需要设置

  1. 。这是通过BPL_JVM_HEAD_ROOM env变量完成的。给它整个容器内存限制的百分之一。例:BPL_JVM_HEAD_ROOM=20将使用容器内存限制的80%用于Java,20用于其他内容。

在其他情况下,设置一些空间也是有用的,例如,如果您正在排除容器崩溃的故障,您需要额外的空间,或者如果您不喜欢在内存限制100%的情况下操作。你可以留出5%或10%的时间来保持舒适。--

如果您的应用程序使用了大量线程,那么

  1. 也需要对此进行调整。默认情况是250个线程,这对于许多基于web/servlet的应用程序(每个请求模型都是线程)很好。如果您专门使用Spring,那么我们会自动降低到50个线程,它不需要那么多线程。

对于其他情况,这取决于您的配置。例如,如果您的批处理应用程序只需要线程池10,则可以设置此40或50。在本例中,40-50似乎很奇怪,但是JVM创建了许多自己的线程,当怀疑查看线程转储时,除了应用程序特定的线程之外,还需要说明这些线程。。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/71425428

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档