【发布时间】:2021-10-26 06:44:09
【问题描述】:
我在 Kubernetes 集群上运行了一个 openjdk:8 映像。我添加了内存 HPA(Horizontal Pod Autoscaling),它可以很好地扩展,但由于 JVM 不会将内存从堆释放回操作系统,因此 Pod 不会缩小。以下是 hpa.yaml
apiVersion: autoscaling/v2beta2
kind: HorizontalPodAutoscaler
metadata:
name: image-server
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: image-server
minReplicas: 2
maxReplicas: 10
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 60
- type: Resource
resource:
name: memory
target:
type: Utilization
averageUtilization: 60
解决此问题的一种方法是使用正确的 GC 并使其释放内存,但由于 JVM 被设计为不会出于性能原因频繁地从堆中释放,因此这样做不是一个好主意。有没有办法从 Kubernetes 处理这个问题?就像不检查操作系统的内存使用情况一样,我们可以不只检查堆中的内存使用情况并在其上进行扩展吗?
【问题讨论】:
-
你是正确的,JVM 通常不会返回内存,但这也不完全正确。看看here 和here, if you are using G1
-
@Eugene 我正在使用 openjdk 8,它默认使用 ParallelGC。出于性能原因,JVM 保留内存以避免分配释放周期,通过使用不同的 GC 或将其配置为更频繁地释放内存可能会增加该周期。而且由于我们只有一个 java 进程在这个 pod 上运行,所以操作系统不需要它来做任何其他事情,即使 Java 保留它也没关系。我正在寻找一种基于堆使用而不是操作系统报告的内存使用来执行 HPA 的方法。
-
你不能。但是您可以使用 diff GC 更快(或根本)释放内存,从而几乎达到您想要的效果。声称由于性能影响而没有这样做的说法已成为过去的神话。每个并发 GC,例如 Shenandoah 和 ZGC(甚至是链接显示的 G1),都会释放它。
标签: kubernetes garbage-collection jvm