What’s the difference between a profiler and a memory analyzer? When would you use each tool?
This article looks at the difference between them, and typical use cases. It also takes a look at a few profilers and memory analyzers that can be used for troubleshooting Java applications.
What is a Java Memory Analyzer, and When Would We Use One?
A Java memory analyzer specifically looks at what data is currently stored in the heap, and doesn’t analyze other aspects of performance.
We’d use one when:
- We suspect an application has a memory leak;
- An application crashes with an Out of Memory error;
- An application uses too much memory, degrading the performance of other running programs;
- We need to accurately configure memory parameters when a program is about to be put live;
- We need to ensure an application is not wasting memory, especially when it’s designed for a small device.
With a memory analyzer, we should be able to see what objects are using the most memory, navigate the object reference tree to find the parents and children of each object, view an object’s contents, and get precise statistics of exactly how much memory is being used, both overall and by class.
Memory leaks can usually be detected by examining and exploring the three or four objects that use the most memory.
What is a Java Profiler, and When Would We Use One?
A Java profiler analyzes many different aspects of the performance of a running program. It may include information about CPU time and memory used, running threads, stack traces and garbage collection activity. It may also include the option to view details of heap usage.
We’d use it to:
- Identify performance bottlenecks;
- Pre-empt performance problems and crashes that may affect production;
- Assist with deciding on the best tuning parameters;
- Monitor pre-production performance and load testing;
- Compare the performance of different design choices;
- Include in CI/CD pipelines to ensure new code is running efficiently.
Choosing Profiler and Memory Analyzer Tools
There are several factors that might affect our choice of tools.
Primarily, of course, we need a tool that will give the right information in a form that’s easy to understand. We also don’t want to waste a lot of time requesting information piecemeal: if we can just press a few buttons and get the information quickly, it’s going to be a big plus in a busy work environment.
We shouldn’t have to invest a lot of time in learning how to use the tools: good documentation and a vibrant support community help a lot when we’re using something new.
In production, we don’t want to use a tool that adds a huge overhead to an already-busy workload. Security is also important, especially when dealing with heap dumps, which may contain confidential information such as credit card numbers.
In some circumstances, such as when we need to urgently troubleshoot problems with a live system, we may have to go with whatever tools are readily available. We may not have time to download and install a good profiler while clients are breathing down our necks for quick answers.
We should also look at what options we have for accessing the tool. Can it be used in the cloud for quick access? Can it work on the actual production server if we don’t want to transfer sensitive information to less secure machines? Can it work via API so it can be incorporated into CI/CD pipelines or continuous monitoring strategies?
Java Troubleshooting Tools
Let’s have a look at a few of the tools you may use when you’re troubleshooting or performance tuning.
1. Memory Analyzers
Let’s look at a few popular tools that analyze heap dumps, allowing us to troubleshoot memory leaks and out of memory errors, as well as giving us useful information about an application’s heap usage.
1.1 HeapHero
This tool is highly popular. It has the advantage that it can be run either in the cloud, on-premise to protect sensitive dumps, or via API calls as part of an automated workflow. It quickly provides comprehensive, interactive reports and graphs. Additionally, it uses machine learning to proactively diagnose potential issues such as memory leaks and wasted memory.
As with most memory analyzers, we first need a heap dump. This is a file containing a snapshot of the heap contents at a given moment. Since the file is in binary, we need to use a memory analyzer to examine its contents. Here’s an article that explains how to take a heap dump.
Below are samples of some of the charts produced by HeapHero.

Fig: Extracts From HeapHero Report
Here’s a link to a demonstration of how to use HeapHero to diagnose memory leaks.
1.2 VisualM
Originally included with the JDK as JVisualVM, this software is now downloadable from GitHub. It’s both a memory analyzer and a profiler. It has an option to take a heap dump from a running process, and explore it. It’s not as comprehensive as HeapHero, but it allows us to explore objects that are taking up a lot of space, and it’s helpful for diagnosing memory leaks. It’s an interactive GUI-based tool. The image below shows a class histogram taken from JVisualVM.

Fig: VisualVM: Exploring Memory
1.3 Eclipse MAT
Eclipse Memory Analyzer (MAT) is a popular and comprehensive tool for exploring heap dumps and identifying memory leaks. It’s an interactive GUI-based utility, allowing the user to quickly obtain a variety of heap-related information.
Its major drawbacks compared to HeapHero are that it doesn’t include ML-generated suggestions, and it runs only on desktop. This means heap dumps must be transferred to the technician’s machine, which is not ideal for sensitive information. It also doesn’t include API access, so it can’t be included as part of automated monitoring.
The image below shows the MAT dashboard.

Fig: Eclipse MAT Dashboard
1.4 JHat
JHat was shipped with the JDK in versions 6 to 16, but was later deprecated and no longer supported. It can, however, be a useful tool if we’re using any of these versions, and have no other options quickly available. When invoked from the CLI, it analyzes a heap dump and produces a report available to a browser on http://localhost:7000. We can then interactively explore different aspects of memory interactively.
The image below shows a section of the class histogram produced by JHat.

Fig: Heap Histogram Produced by JHat
1.5 Summary
The table below summarizes the features offered by these memory analyzer tools.
| Popular Memory Analyzers: Feature Summary | ||||
| HeapHero | Eclipse MAT | VisualVM | JHat | |
| Identify memory leak suspects | ✔️ | ✔️ | – | – |
| Explore dominator tree | ✔️ | ✔️ | – | – |
| Comprehensive data: Histograms, thread info, GC roots, retained heap | ✔️ | ✔️ | Partial | Partial |
| Memory usage stats by generational region | ✔️ | – | ✔️ | ✔️ |
| Flexible Deployment | ✔️ | – | – | – |
| Include ML recommendations | ✔️ | – | – | – |
| Wasted Space analysis | ✔️ | ✔️ | – | – |
| Protect sensitive data | ✔️ | – | – | – |
| OQL | ✔️ | ✔️ | – | ✔️ |
| Integrate with CI/CD | ✔️ | – | – | – |
| Support large heap dumps | ✔️ | ✔️ | – | – |
2. CLI Tools
The JDK includes several command line tools for quickly obtaining information from a running process. These are useful for quickly pulling out a few key metrics when no other tools are available, but they require a high level of expertise, and it tends to be time-consuming to obtain a range of meaningful information. They include:
- Jcmd: This is an all-purpose diagnostic and control tool, which sends commands to a running JVM. It can be used for many things, including taking a heap dump, viewing GC stats and controlling flight recordings.
- Jstat: Obtains real-time statistics from a running JVM. Examples include summaries of GC activity, memory usage and class loaders.
- JMap: This can be used to obtain useful information for monitoring memory usage, and diagnosing issues. It can initiate a heap dump, list objects awaiting finalization, extract a class histogram and more.
- Jstack: This is useful for diagnosing thread-related issues. It prints the stack trace and status of each running thread.
- Jfr: Controls Java flight recordings. These can be used by profilers such as JMC to obtain detailed information about many aspects of a JVM.
- jps: This is the quickest way to obtain the PID of a running JVM. The PID needs to be specified for most of the utilities in the JDK toolkit.
These tools are good for obtaining a quick glance at the performance of an application, but analyzing their output can be time-consuming, and they’re often used in conjunction with a Java profiler.
Outside of the JDK, a more comprehensive tool is the open-source yCrash script, downloadable for free from GitHub. This CLI-based script captures 360° data about the JVM and its environment, giving one-command access to all the diagnostics we need to troubleshoot performance problems.
It includes information about the heap, thread stacks and status, GC statistics and other critical JVM artefacts. Additionally, it extracts data regarding networking, kernel error messages and resources used by other applications running in the device or container.
This information can either be assessed manually, or uploaded to the yCrash dashboard for analysis.
3. Java Profilers
In this section, we’ll look at some popular Java profiler tools. These give us information about an application’s performance and requirements, helping us find the source of any bottlenecks in the system.
3.1 Async-profiler
This is a comprehensive profiling tool, allowing us to request a wide range of information using simple CLI commands.
Some examples of information that can be requested using this profiler include:
- CPU usage analysis;
- Heap allocations;
- Native memory allocations;
- Stack traces for both application and non-application threads, such as GC and the JIT compiler;
- Contended locks;
- Hardware and system software performance statistics.
It’s a powerful tool for troubleshooting running applications. The image below shows a flame graph produced by Async-profiler. This is useful for analyzing which methods are actually causing bottlenecks.

Fig: Flame Graph Produced by Async-profiler
3.2 Java Mission Control (JMC)
JMC is a GUI-based tool downloadable from Oracle. It allows us to explore various aspects of a running JVM process interactively. A dashboard gives quick statistics of the process, as shown in the image below.

Fig: JMC Dashboard
From there, we can access more detailed information about various areas related to performance.

Fig: JMC MBean Browser
When working on older versions of the JVM, it may be necessary to activate Java Flight Recording on the target process before we can use JMC.
3.3 JConsole
Since this tool is part of the JVM, it’s a good choice for quickly viewing performance statistics in a situation where other tools aren’t installed.
It allows us quick insights into a running program via an interactive GUI.

Fig: JConsole Diagnostics
3.4 VisualVM
As mentioned earlier, VisualVM is a Java profiler as well as a memory analyzer.
Like JConsole, it gives us quick insights into performance issues.

Fig: VisualVM Monitoring Console
Conclusion
Java profilers and Java memory analyzers each have a place in the troubleshooter’s toolbox.
Memory analyzers are used to debug memory leaks and out of memory errors, as well as to ensure memory is being used efficiently.
Java profilers are used to troubleshoot runtime performance issues, as well as to make sure applications are making optimal use of resources before being introduced into production.
This article has looked at various useful examples of these two kinds of tools, including HeapHero for diagnosing memory issues, and yCrash for performance monitoring and troubleshooting.
If you’re working with high-performance systems, it’s essential to become familiar with both profilers and memory analyzers.

Share your Thoughts!