在 kubernetes 仪表板上,有一个 pod,其中内存使用情况(字节)显示为904.38Mi.
此 pod 包含使用-Xms512m -Xmx1024m, 和 kubernetes 部署文件 -> requests.memory = 512M,运行的 Java 应用程序limits.memory = 1.5G。
我已启用 gc 日志并在 pod 日志中看到这些:
[2020-04-29T15:41:32.051+0000] GC(1533) Phase 1: Mark live objects
[2020-04-29T15:41:32.133+0000] GC(1533) Phase 1: Mark live objects 81.782ms
[2020-04-29T15:41:32.133+0000] GC(1533) Phase 2: Compute new object addresses
[2020-04-29T15:41:32.145+0000] GC(1533) Phase 2: Compute new object addresses 11.235ms
[2020-04-29T15:41:32.145+0000] GC(1533) Phase 3: Adjust pointers
[2020-04-29T15:41:32.199+0000] GC(1533) Phase 3: Adjust pointers 54.559ms
[2020-04-29T15:41:32.199+0000] GC(1533) Phase 4: …Run Code Online (Sandbox Code Playgroud) java garbage-collection memory-management kubernetes kubernetes-metrics
我有一个在 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
Run Code Online (Sandbox Code Playgroud)
解决此问题的一种方法是使用正确的 GC 并使其释放内存,但由于 JVM 出于性能原因设计为不会频繁地从堆中释放内存,因此这样做并不是一个好主意。Kubernetes 有办法处理这个问题吗?就像不检查操作系统的内存使用情况一样,我们是否可以只检查堆和缩放中的内存使用情况?
IDE:IntelliJ、JDK 16.0.2
代码:
public static void main(String[] args) {
Runtime runtime = Runtime.getRuntime();
System.out.println("Free memory before gc: " + runtime.freeMemory() / (1024 * 1024) + " Mb");
runtime.gc();
System.out.println("Free memory after gc: " + runtime.freeMemory() / (1024 * 1024) + " Mb");
}
Run Code Online (Sandbox Code Playgroud)
输出:
Free memory before gc: 251 Mb
Free memory after gc: 13 Mb
Run Code Online (Sandbox Code Playgroud)
问题:为什么调用垃圾回收“吃掉”所有内存?
我使用默认的垃圾收集器(G1GC)运行java应用程序。我不知道 G1CC 何时确切释放内存。我看到应用程序使用了htop它。700M我这样做后,jcmd <pid> GC.run它下降到大约250M。这是否意味着 GC 不会自行执行此操作?