垃圾收集器 Java 应用程序在 POD Kubernetes 中不能释放内存。

huangapple go评论70阅读模式
英文:

Garbage Collector Java application does not free memory in POD Kubernetes

问题

以下是翻译好的内容:

我在应用程序的垃圾收集器方面遇到了问题,我正在一个GCP环境中使用Kubernetes,并将BigTable作为数据源。

在接收负载时,应用程序不释放内存空间,直到k8s重新启动POD。我使用分析器来查看JVM的行为,以下是结果。

在“Old Gen”池中,可以看到内存已满,但它从不释放空间,并且会一直填充,直到重新启动并重新开始。

垃圾收集器 Java 应用程序在 POD Kubernetes 中不能释放内存。

在“Eden Space”池中,可以看到虽然它在填充,但空间会被释放,从未达到限制。

垃圾收集器 Java 应用程序在 POD Kubernetes 中不能释放内存。

以下是创建Docker映像以在k8s中部署时的JVM配置。

java
-XX:+UnlockExperimentalVMOptions
-XX:+UseG1GC
-XX:+UseCGroupMemoryLimitForHeap
-XX:+AlwaysPreTouch
-XX:ParallelGCThreads=5
-XX:GCTimeRatio=4
-XX:MaxGCPauseMillis=100
-XX:MinHeapFreeRatio=30
-XX:MaxHeapFreeRatio=30
-Xms512m
-Xmx4608m

这个相同的配置应用于另一个进行REST调用的应用程序,而该应用程序从未像这种情况一样出现内存填充问题。

Java版本为1.8。

感谢您的帮助。

问候。

英文:

I have a problem with the Garbage Collector of my application, I am working in a GCP environment with Kubernetes and BigTable as a data source.

Upon receiving loads, the application does not free up memory space and fills up until k8s restarts the POD. I use a profiler to see the behavior of the JVM and this is the result.

In the "Old Gen" pool it is seen that the memory is full but it never frees the space and it fills up until restarting and starting again.

垃圾收集器 Java 应用程序在 POD Kubernetes 中不能释放内存。

In the pool "Eden Space" it is seen that while it is filling, the space is freed and never reaches the limit.

垃圾收集器 Java 应用程序在 POD Kubernetes 中不能释放内存。

This is the JVM configuration when creating the docker image to deploy it in k8s.

java
-XX:+UnlockExperimentalVMOptions
-XX:+UseG1GC
-XX:+UseCGroupMemoryLimitForHeap
-XX:+AlwaysPreTouch
-XX:ParallelGCThreads=5
-XX:GCTimeRatio=4
-XX:MaxGCPauseMillis=100
-XX:MinHeapFreeRatio=30
-XX:MaxHeapFreeRatio=30
-Xms512m
-Xmx4608m

This same configuration is applied in another application that makes REST calls and has never had memory filling problems as in this case.

Java version is 1.8

Thankful for your help.

Grettings.

答案1

得分: 2

首先,您必须确定问题的根本原因,以便进一步处理。我建议您使用 -XX:+PrintGCDetails 和 -XX:+PrintGCTimeStamps 收集有关该主题的更多信息。如果您的假设“Old Gen”池从未释放空间是正确的(老实说,从图像上并不明显),您可以尝试一些技巧来处理它,比如:

  • 通过 -XX:MaxNewSize、-XX:NewSize、-XX:MaxOldSize、-XX:MaxOldSize 直接指定新生代和老年代的大小,以确保有足够的空间供老年代使用。
  • 通过 -XX:+PrintGCDetails 和 -XX:+PrintGCTimeStamps 收集更多日志,以查看是否由于某一代的过度利用而导致任何问题。
  • 尝试通过 -XX:SurvivorRatio 增加幸存者空间比例,以加速老年代对象的收集。
英文:

Firstly, you have to identify the root cause of your problem to proceed further. I would suggest you to collect more information on the topic with -XX:+PrintGCDetails and -XX:+PrintGCTimeStamps. If your hypothesis that "Old Gen" pool is never frees the space is correct (honestly spearking, it's not obvious from the image), you might apply few tricks to deal with it as such:

  • Directly specify new and old gc sizes via -XX:MaxNewSize, -XX:NewSize, -XX:MaxOldSize, -XX:MaxOldSize to ensure that there is enough space for old generation
  • Gather more logs via -XX:+PrintGCDetails and -XX:+PrintGCTimeStamps to see if any issue happens due to over utilizing of one of the generations
  • Try to increase survivor space ratio via -XX:SurvivorRatio to expedite collection of the old generation objects

huangapple
  • 本文由 发表于 2020年9月7日 09:15:37
  • 转载请务必保留本文链接:https://go.coder-hub.com/63770281.html
  • garbage-collection
  • java
  • jvm
  • kubernetes
  • kubernetes-pod
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定