1. Overview

Java is well known for its excellent Garbage Collector algorithms. However, that does not mean memory leaks cannot happen in the JVM application. Getting and analyzing a heap dump is the first step to finding a potential leak in our app.

In this short tutorial, we’ll see how to get a Java heap dump from the app running as a Kubernetes pod.

First, we’ll investigate what a heap dump is. Then, we’ll create a small test application that will later be deployed to Kubernetes as a pod. Finally, we’ll see how to get a heap dump from it.

2. What Is a Heap Dump

A heap dump is a snapshot at a certain moment in time of all the objects that are in the JVM app’s memory.

By looking at the heap and analyzing it with special tools, we can locate where objects are created and find the references to those objects in the source. We can also see a graph showing memory allocation throughout time.

Because of that, a heap dump helps to detect memory-leak problems and optimize memory usage in JVM applications.

3. Creating a Test Application

Before we capture a heap dump, we need a working JVM application in a Kubernetes pod.

3.1. Creating a Long Running Application

Let’s create a simple app that searches for prime numbers in the specified range. We’ll call it prime-number-finder.

Our small application consists of a main() method and an isPrime() method to run a brute force prime detector:

public static void main(String[] args) {
    List<Integer> primes = new ArrayList<>();
    int maxNumber = Integer.MAX_VALUE; // set to huge to make it run a long time

    for (int i = 2; i < maxNumber; i++) {
        if (isPrime(i)) {
            System.out.println(i);
            primes.add(i);
        }
    }
}

private static boolean isPrime(int number) {
    return IntStream.rangeClosed(2, (int) (Math.sqrt(number)))
      .allMatch(n -> number % n != 0);
}

The next thing is to compile our code to a jar file. It’ll be called prime-number-finder.jar and will be located in the target directory.

3.2. Containerizing the Application for Kubernetes

To be able to deploy it to the Kubernetes stack, let’s create a dockerfile:

FROM adoptopenjdk:11-jre-hotspot

COPY target/prime-number-finder.jar application.jar
ENTRYPOINT ["java", "-jar", "application.jar"]

We’re copying the built jar file into a container and running it using the standard java -jar command.

Next, we need a prime-deploy.yaml Kubernetes deployment file that specifies how to deploy our app to the Kubernetes stack:

apiVersion: v1
kind: Pod
metadata:
  name: prime-number-finder-pod
spec:
  containers:
    - name: prime-number-finder
      image: baeldung/prime-number:latest

The last thing we need to do is to deploy it to Kubernetes:

$ kubectl apply -f prime-deploy.yaml

We can use kubectl get pods command to check, if the deployment was successful:

NAME                      READY   STATUS             RESTARTS   AGE   IP           NODE
prime-number-finder-pod   1/1     Running             0         1m   172.17.0.3   minikube   

4. Getting a Heap Dump

The first thing we need to do is to get the running pod’s name. We can take it from the kubectl get pods command from the previous chapter. In our case, it’s prime-number-finder-pod.

The next step is to use that name to get into our running pod. We’ll use the Kubernetes exec command to do that:

$ kubectl exec -it prime-number-finder-pod bash

Now, we need to get the process id of our running JVM app. We can use the jps command which is built into the JDK.

The next step is to create the heap dump. Once more, we’ll use a built-in JDK tool:

$ jmap -dump:live,format=b,file=prime_number_heap_dump.bin <process_id>

The last thing we need to do is to copy the newly created heap dump from the pod to our local machine:

$ kubectl cp prime-number-finder-pod:prime_number_heap_dump.bin <our local destination directory>

Now, we can use any memory analysis tool, such as JvisualVM provided with JDK, or 3rd-party applications, such as JProfiler or JStack Review, to analyze the heap dump

This is what a 10-minute prime number app’s heap dump analysis in JvisualVM looks like:

prime number heap dump

5. Conclusion

In this article, we learned how to get a Java heap dump from a Kubernetes pod.

First, we understood what a heap dump is and its purpose. Then, we created a simple prime number finder application and deployed it to Kubernetes.

Finally, we showed how to log into the running pod, create a heap dump and copy it to a local machine.

As always, the complete source code of the article is available over on GitHub.

Comments are open for 30 days after publishing a post. For any issues past this date, use the Contact form on the site.