Java GC运行导致操作系统上mem使用量增加
在过去的日子里,我看到了一些行为,这些行为打破了我的一些假设。也许有人能给我解释一下 事实Java GC运行导致操作系统上mem使用量增加,java,docker,kubernetes,garbage-collection,Java,Docker,Kubernetes,Garbage Collection,在过去的日子里,我看到了一些行为,这些行为打破了我的一些假设。也许有人能给我解释一下 事实 我们正在GCP的K8s中的Docker容器中运行Java应用程序 我们的基本映像是openjdk:8u171 jre slim stretch 我们使用了标志-XX:+UnlockExperimentalVMOptions-XX:+UseCGroupMemoryLimitForHeap=>所以资源限制应该从容器中获得,而不是从主机=>IMO中获得 我们参与了XX:MaxRAMFraction=2所以我们
- 我们正在GCP的K8s中的Docker容器中运行Java应用程序
- 我们的基本映像是openjdk:8u171 jre slim stretch
- 我们使用了标志
=>所以资源限制应该从容器中获得,而不是从主机=>IMO中获得-XX:+UnlockExperimentalVMOptions-XX:+UseCGroupMemoryLimitForHeap
- 我们参与了
所以我们得到了堆=>IMO的容器内存限制的一半XX:MaxRAMFraction=2
- JVM没有设置
-Xmx
- 影响JVM内存的唯一方法是通过Kubernetes resource limits=>这正是我们想要的
当GC启动(清除或G1)时,
容器内存使用量
,而不是jvm内存使用量
。为什么GC使用容器中的内存?好的,它会把东西从老一代复制到年轻一代,所以我知道在短时间内会使用更多的内存。但是我已经预料到这将来自JVM进程,而不是一些内核进程 在运行Java pod的K8s集群中设置内存和CPU限制时,我们遇到了一些问题,Prometheus中的pod内存使用率更高(甚至一些pod由于探测错误而崩溃)
在进一步分析时,我们发现GC正在努力释放内存,因为与对象创建相比,限制太小了;使CPU周期花费在GC上;而不是实际工作。我们通过增加pod内存限制来避免这种情况
所以,也许你可以增加提供给POD的最大内存限制,看看这是否会消失。我不确定这是否会对你有帮助,但我想分享一下,以防万一