Operations 8 min read

Mastering JVisualVM: Detect Memory Leaks and Monitor Java Apps

This guide introduces JVisualVM, explains its installation and plugin system, demonstrates how to create a memory‑leak example, use VisualGC and sampling tools to identify leaking objects, and shows step‑by‑step remote monitoring of a Tomcat server via JMX, providing practical screenshots and code snippets.

Programmer DD
Programmer DD
Programmer DD
Mastering JVisualVM: Detect Memory Leaks and Monitor Java Apps

JVisualVM Overview

VisualVM is a profiling tool originally part of NetBeans, bundled with JDK 6u7 and later. It provides a visual interface to monitor threads, memory usage, CPU time of methods, garbage‑collected objects, and to view stack traces of allocations.

It can monitor both local and remote Java applications, and its data can be saved for later analysis.

Installation and Plugins

After installing JDK, the executable jvisualvm.exe is located in the bin directory. Launching it shows a UI similar to jconsole.

The main window is shown below:

Plugins can be installed via Tools → Plugins. Select the desired plugins (e.g., GC, Memory, Threads) and click Install.

1. Choose “Tools” → “Plugins”. 2. In the “Available Plugins” tab, check the plugins to install. 3. Click “Install” and follow the wizard.

Example: Simulating a Memory Leak

The following code creates a static HashMap and repeatedly adds objects to it, causing a memory leak.

import java.util.HashMap;
import java.util.Map;
public class CyclicDependencies {
    private static final Map map = new HashMap();
    public static void main(String[] args) {
        try { Thread.sleep(10000); } catch (InterruptedException e) { e.printStackTrace(); }
        // add objects to the cache
        for (int i = 0; i < 1000000; i++) {
            TestMemory t = new TestMemory();
            map.put("key"+i, t);
        }
        System.out.println("first");
        // repeat several times with different loop counts
        // ...
        try { Thread.sleep(Integer.MAX_VALUE); } catch (InterruptedException e) { e.printStackTrace(); }
    }
}

JVM options used for the test:

-Xms512m
-Xmx512m
-XX:-UseGCOverheadLimit
-XX:MaxPermSize=50m

Analyzing the Leak with JVisualVM

Open the VisualGC tab to see GC activity after each print statement. Screenshots show increasing heap usage and GC cycles, indicating objects that cannot be reclaimed.

Use the Sampler tab to take heap dumps at “second” and “forth” outputs, then compare the dumps. The comparison reveals that TestMemory instances keep growing.

Inspect the instance view of TestMemory to see that it is referenced from the static HashMap, confirming the leak source.

Remote Monitoring of Tomcat

Configure the Tomcat server’s catalina.sh to expose JMX:

JAVA_OPTS="$JAVA_OPTS
-Djava.rmi.server.hostname=192.168.122.128
-Dcom.sun.management.jmxremote.port=18999
-Dcom.sun.management.jmxremote.ssl=false
-Dcom.sun.management.jmxremote.authenticate=false"

In JVisualVM, add a remote host, create a JMX connection using the configured port, and connect to the Tomcat process.

After connecting, you can monitor threads, memory, and GC of the remote Tomcat instance just like a local application.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

Performance MonitoringTomcatjmxJava profilingJVisualVM
Programmer DD
Written by

Programmer DD

A tinkering programmer and author of "Spring Cloud Microservices in Action"

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.