Blog Post

Apps on Azure Blog
3 MIN READ

Capture a JVM heap dump for Java apps running on Azure Container Apps

croffz's avatar
croffz
Icon for Microsoft rankMicrosoft
Mar 13, 2025

Overview

Capturing a JVM heap dump is one of the most widely used debugging techniques for troubleshooting memory issues in Java applications. It might be not that straight-forward when it comes to cloud services, but in Azure Container Apps, you can do a JVM heap dump easily with the help of the debug console.

Connect to the debug console of a running Azure Container Apps instance

With the Azure CLI and the latest Azure Container Apps extension installed, run the following command to connect to the debug console.

az containerapp debug \
    --resource-group <resource-group> \
    --name <container-app-name>

To use JDK built-in tools to capture a JVM heap dump, run the following command to install the JDK after connected to the debug console:

root [ / ]# setup-jdk

Then, use arrow up (↑) and down (↓) to select the JDK version to install. We detect your app runtime environment and recommend a JDK version for you. For example:

Select a JDK to install:
  [temurin-8-jdk]: Eclipse Temurin JDK 8
  [msopenjdk-11]: Microsoft Build OpenJDK 11
  [msopenjdk-17]: Microsoft Build OpenJDK 17
 >[msopenjdk-21]: Microsoft Build OpenJDK 21 (Recommended)

[Optional] Switch user context

In the debug console session, a Java app is usually the process 1, with its files stored at /proc/1, if no customizations are made in the image. (Otherwise, you might need to get the correct process ID of the Java application). However, if the Java app to be profiled is run by a non-root user (which is also defined in the image), you cannot access anything in /proc/1 directly given that the debug console starts as root by default.

root [ / ]# ls /proc/1/root ls: cannot access '/proc/1/root': Permission denied

To work this around this issue, use the following command to switch the user context.

root [ / ]# switch-user
Switching to user app...
app [ / ]$ 

The user context will then be changed to the one that runs the Java application, and you can capture a JVM heap dump with it.

Capture a JVM heap dump

jmap and jcmd are both built-in tools in the JDK to help you capture a JVM heap dump. They are all located under the bin folder inside the JDK home directory.

To capture a JVM heap dump by using jmap, run the following command in the debug console:

app [ / ]$ jmap -dump:live,format=b,file=/tmp/dump.hprof 1

To capture a JVM heap dump by using jcmd, run the following command in the debug console:

app [ / ]$ jcmd 1 GC.heap_dump /tmp/dump.hprof

Either way, you can then access the dump file at /proc/1/tmp/dump.hprof.

Download the dump file to local

Transferring files from cloud services to local could be tricky sometimes. But in the Azure Container Apps debug console, you can download the dump file with the help of Azure Cloud Storage. There are several options:

  1. Mount an Azure Storage File Share as a volume to Azure Container Apps.
  2. Send an HTTP request to Azure Blob Storage to upload the file from the debug console session.
  3. Use AzCopy to save the effort of constructing an upload HTTP request and use Azure authentication instead.

In this article, we focus on the 3rd approach.

 

Step 1: Install AzCopy in the debug console session. Note that this step needs to be done as the root user. If the current user is not root, type "exit" to get back to the root context.

root [ / ]# tdnf install -y azcopy

Step 2: Authenticate with Azure Entra ID.

root [ / ]# azcopy login

Step 3: Copy the dump file to Azure Blob Storage.

root [ / ]# azcopy copy "/proc/1/tmp/dump.hprof" "https://<storage-account-name>.blob.core.windows.net/<blob-storage-name>/dump.hprof"

Step 4: Download the dump file from Azure Blob Storage by using the Azure Portal or the Azure CLI on the local machine.

Updated Mar 12, 2025
Version 1.0
No CommentsBe the first to comment