带有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配置,或者我可以以某种方式重新配置它?
发布于 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点)。
使用内存计算器,当容器第一次开始确保内存设置正常时,它就会进行计算。如果配置有问题,就会失败,并通知您。
提示:
JAVA_TOOL_OPTIONS env变量中设置JAVA_TOOL_OPTIONS选项来覆盖内存计算器定义的值。例如,如果我想允许更直接的内存,我会设置JAVA_TOOL_OPTIONS='-XX:MaxDirectMemorySize=50M'。然后,当您重新启动容器时,内存计算器将移动内存以容纳它。,
-Xmx。内存计算器应该始终设置这一点,因为它会将其设置为在其他区域计算完毕后所剩的任何内容。你可以把它想象成HEAP = CONTAINER_MEMORY_LIMIT - (all static memory regions)。如果要设置-Xmx,就必须完全正确。如果太低,那你就是在浪费记忆。如果它太高,那么您可能会超过容器内存限制,从而导致崩溃。
简而言之,如果您认为要设置-Xmx,则应该增加容器内存限制或减少一个静态内存区域。
如果在容器中运行其他内容,则需要设置
BPL_JVM_HEAD_ROOM env变量完成的。给它整个容器内存限制的百分之一。例:BPL_JVM_HEAD_ROOM=20将使用容器内存限制的80%用于Java,20用于其他内容。在其他情况下,设置一些空间也是有用的,例如,如果您正在排除容器崩溃的故障,您需要额外的空间,或者如果您不喜欢在内存限制100%的情况下操作。你可以留出5%或10%的时间来保持舒适。--
如果您的应用程序使用了大量线程,那么
对于其他情况,这取决于您的配置。例如,如果您的批处理应用程序只需要线程池10,则可以设置此40或50。在本例中,40-50似乎很奇怪,但是JVM创建了许多自己的线程,当怀疑查看线程转储时,除了应用程序特定的线程之外,还需要说明这些线程。。
https://stackoverflow.com/questions/71425428
复制相似问题