One of the practices when dealing with memory leak issues is to take a heap dump and analyze it to figure out which part of the code is causing the leak. The method of capturing heap dump varies depending on the technology stack. It is not limited to a single silver bullet. Some frameworks like Spring Boot allow exposing an actuator endpoint to get a heap dump, and some provide CLI tools. The standard JDK also has a utility called jcmd
that can capture heap dump of any running JVM process. In this article, we discuss how to capture Java apps heap dumps on Kubernetes. The approach is framework-independent which means we only use the good old jcmd
command.
This article is specifically written to provide the simplest and quickest way to capture a heap dump. Obviously, it’s neither the best nor the most scalable. The goal is to quickly get a heap dump at the time of crisis. That’s why it’s called the poor man’s way 🙂
Prerequisite
You need to have SSH permission to the Kubernetes pod in mind. That means you need to have the kubectl
configured and pointed to the correct environment. Additionally, the pod that the application is running on should have jcmd
installed.
Capture the heap dump inside of the Kubernetes pod
First, we need to get the PID of the JVM process we want to get the dump.
$ jcmd
Then take a heap dump,
$ jcmd [jvm_process_pid] GC.heap_dump [path+file_name]
Transfer the heap dump
So far the heap dump is only available on the Kubernetes pod. Now we need to copy it to the local machine. For that we use K8s cp
which resembles to scp
command,
$ kubectl -n [namespace] cp [namespace]/[pod_name]:[absolute_path+file_name] [local_machine_path]
Once we have the heap dump, we can use a tool like Eclipse Memory Analyzer for inspection.
That’s all on how to capture Java apps heap dumps on Kubernetes. For more Java and Spring content check here and here.
Inline/featured images credits
- Featured image by Dean Moriarty from Pixabay