I have java(spring boot framework version: 2.7.11 & open jdk:11) based microservice. When this microservice is not serving any requests, each pod of the microservice is using about 470MB. We have kept the memory limit as 1200Mi for this microservice and this microservice is deployed on K8 and max heap is -Xmx750M.
I did some load testing on this microservice. On this microservice, I made 20 API around requests per second. A consistent pattern that I have observed is that: the memory utilization goes up as I increase the load and memory does not get released after the load stop. Once I complete the load testing, I wait for an hour or so. Yet, the memory utilization does not come down. The pod continues occupying same amount of memory as before. I also got a shell inside the container of such a pod, I can see only the java process and the sh process running. And indeed, I see that memory usage of the pod has increased to about 1024MB.
So, a pod which usually takes 470MB (in absence of any load testing), takes 1024MB under load test, and continues to use 1024MB long after the load testing has completed. As I can see max heap size is not going beyond 400-500M.
I do not understand why the pod usage is not coming down.
Could it be:
JVM heap usage problem, probably garbage collection not happening? Something related to Kubernetes pod requests and limits settings? Here are my requests and limits for Kubernetes pods:
resources: limits: memory: 1200Mi cpu: 1 requests: memory: 900Mi cpu: 1 By the way, I am using Apache JMeter for API load testing. The Docker image being used is : oracle openjdk:8 I also downloaded the heap dump and opened it in Eclipse Memory analyzer tool. But, I do not see any application classes (from our code) using a lot of heap. I see classes related to JDK and Spring Boot framework only, and they do not show any memory leak.
So, the mystery for me is : why does memory usage not come down even 7-8 hours after load testing? Is it the Kubernetes config of requests and limits OR is it the JVM GC settings tuning? Is it possible that JVM GC settings are not playing nicely with Kubernetes requests and memory limits?
I have mentioned all things in above description.