Java 8在容器中运行时,默认情况下是否总是消耗至少1GB的RAM?

Java 8在容器中运行时,默认情况下是否总是消耗至少1GB的RAM?,java,docker,kubernetes,jvm,Java,Docker,Kubernetes,Jvm,我们正在Kubernetes集群中运行Java应用程序。应用程序本身对RAM的要求不高,但我注意到它总是消耗1GB的内存 kubectl top pods NAME CPU(cores) MEMORY(bytes) my-application-c0ffee 100m

我们正在Kubernetes集群中运行Java应用程序。应用程序本身对RAM的要求不高,但我注意到它总是消耗1GB的内存

kubectl top pods
NAME                                                              CPU(cores)   MEMORY(bytes)
my-application-c0ffee                                             100m           1127Mi
my-application-c0ffee                                             100m           1109Mi
当我在容器中选中
jcmd GC.heap\u info
时,我得到了以下信息:

def new generation   total 89216K, used 12090K [0x00000000bc200000, 0x00000000c22c0000, 0x00000000d2c00000)
  ...
tenured generation   total 197620K, used 151615K [0x00000000d2c00000, 0x00000000decfd000, 0x0000000100000000)
  ...
Metaspace       used 146466K, capacity 152184K, committed 152576K, reserved 1183744K
  class space    used 18171K, capacity 19099K, committed 19200K, reserved 1048576K
据我所知,默认情况下Java保留1GB的虚拟内存大小用于存储类信息(为了使用32位引用以压缩方式引用它,应该事先保留此内存块)。当在容器外运行时,这不是什么大问题,因为这个内存实际上没有提交。这只是一个被保留的地址空间

但在容器中运行时,情况似乎完全不同,在容器中,保留内存被提交

这是否意味着在容器中运行的Java在默认情况下将消耗至少1GB的RAM? 除了显式地设置
-XX:CompressedClassSpaceSize
,还有其他方法来处理这个问题吗

在容器内运行时,保留内存将被提交

否,保留内存不会“提交”。无论是否在容器中,虚拟大小和驻留集大小都是不同的度量。位于物理内存中的是RSS

kubectl top
不显示RSS,而是显示所谓的“工作集”,它并不总是与实际内存使用情况相匹配

这是否意味着在容器中运行的Java在默认情况下将消耗至少1GB的RAM

没有

还有别的办法吗

这取决于你的目标。如果您想查看实际的容器内存统计信息,请查看
/sys/fs/cgroup/memory/../memory.stats
memory.usage(以字节为单位)
。或者,如果您使用docker,请运行
docker stats


如果您想减少进程的虚拟内存,请关闭
-XX:-UseCompressedClassPointers

我绝对不知道如何处理“工作集”。所以你们的DevOp看到那个数字,你们两个都看它。。。然后呢?这不是没用吗?这个工作集内存会影响容器调度(阻止新容器启动),还是会导致容器被
OOMKilled
?我应该担心这个1GB在工作集中吗?@AleksandrErokhin OS会在cgroup
内存时终止容器中的进程。使用量(以字节为单位)达到
内存。限制(以字节为单位)内存。这是需要关注的关键数字。不确定“工作集”(我不是k8s方面的专家),因为它可能会影响自动缩放等功能。@apangin所以我检查了内存统计信息,似乎top显示的所有内存都会出现在
rss
中。我想我需要更深入地了解这一点。