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

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

kubectl top pods
NAME                                                              CPU(cores)   MEMORY(bytes)
my-application-c0ffee                                             100m           1127Mi
my-application-c0ffee                                             100m           1109Mi

当我检查jcmd <pid> GC.heap_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.statsmemory.usage_in_bytes。或者,如果您使用 docker,请运行docker stats.

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


以上是默认情况下,Java8在容器内运行时是否总是消耗至少1GB的RAM?的全部内容。
THE END
分享
二维码
< <上一篇
下一篇>>