Free tools Windows power users keep installed
One-click scans. No signup required.
A Java process can run out of memory even when its heap looks healthy. The cause may be Metaspace, another HotSpot-managed native-memory category, allocations made by JNI or third-party native libraries, or pressure from the operating system or container. Start with the exact error or crash evidence; then use Native Memory Tracking (NMT) if it was enabled at JVM startup, and investigate memory beyond NMT’s scope when its report does not explain the process footprint.
First identify what failed
Do not treat every OutOfMemoryError as a full Java heap. Oracle’s Java SE 17 troubleshooting guidance distinguishes failures involving the heap, Metaspace, compressed class space, native allocation, and native methods. The exception’s detail message, stack trace, and whether the process threw an exception or crashed help determine which path to follow.
Java heap space: investigate heap use and the configured heap limit. A too-small heap or pool can cause this error without a memory leak.- Metaspace or compressed class space: investigate class metadata usage and the relevant limit rather than assuming ordinary heap exhaustion.
- Native allocation failure or a failure in a native method: investigate HotSpot’s native allocations, JNI and native libraries, and available system resources.
- Process terminated or crashed without a useful Java exception: preserve the fatal error log and, if available, a core dump. Native code that does not handle a failed allocation correctly can cause a crash instead of a clean Java exception.
Before changing memory limits, record the complete exception and stack trace, JVM vendor and version, operating system, container or process limits, and configured heap and Metaspace limits. Also determine whether the observed memory is Java heap usage, JVM-reported native memory, or whole-process/container usage. Raising -Xmx without that distinction can leave less physical or container memory for native components.
Use NMT to examine HotSpot-managed memory
HotSpot’s Native Memory Tracking reports memory used internally by the HotSpot VM. It is off by default and must be enabled when the JVM starts; it cannot be switched on or restarted for an already-running process. Oracle’s Java SE 21 documentation describes two modes:
Outdated Drivers Are Slowing You Down
One free scan finds every outdated or missing driver and matches the right update for your exact hardware.Free scan · exact hardware matchWindows Errors? Fix Them Before They Spread
Repair common Windows errors and clear accumulated junk for a smoother, more stable PC - no reinstall needed.Free scan · no reinstall| Startup option | What it provides | When it helps |
|---|---|---|
-XX:NativeMemoryTracking=summary |
Memory totals grouped by HotSpot subsystem. | Use first to see which broad tracked category is growing. |
-XX:NativeMemoryTracking=detail |
Summary data plus individual call-site details and a virtual-memory map. | Use when subsystem totals are not specific enough to locate growth. |
For example, start the application with the option appropriate to the desired detail level, reproduce or observe the memory growth, and query the running process with jcmd:
jcmd <pid> VM.native_memory summary
jcmd <pid> VM.native_memory baseline
jcmd <pid> VM.native_memory summary.diff
Take a baseline early, then compare a later report with it. For more granular comparisons, use detail and detail.diff; add a scale such as scale=MB when it makes the output easier to read. The exact command syntax and behavior should be checked against the JDK used by the application.
Rank #2
Read reserved and committed values separately
A large reserved value is not the same as memory actively committed for use. Oracle’s Java SE 24 troubleshooting guide, published August 13, 2025, says committed memory is what is actually used and warns that increasing committed memory can lead to swapping or native out-of-memory situations. Use the categories and changes in the report to guide investigation; do not infer current physical consumption from a reservation alone.
Account for NMT’s overhead and timing requirement
Oracle’s Java SE 21 documentation gives a 5%–10% performance-overhead range for enabling NMT. Treat that as Oracle’s documented range, not a measured guarantee for every application or JVM build; validate the operational cost on the target runtime and workload. Because NMT must be enabled at startup, a process already running without it must be restarted with tracking enabled before a reproduction can be captured.
When NMT does not explain process memory
NMT is not a complete ledger of process memory. Oracle states: “NMT does not track memory allocations for third-party native code and Oracle Java Development Kit (JDK) class libraries.” It also does not provide complete information about memory used by the Class Data Sharing (CDS) archive. JNI code and native libraries may allocate outside the categories NMT reports.
If the operating-system or container view shows growth while NMT categories remain stable, compare those measurements with JVM reports and investigate the native components that own the relevant allocations. Oracle’s Java SE 17 troubleshooting guidance names several possible tools, but their usefulness depends on the operating system, JVM, libraries, and workload:
Rank #4
| Evidence or tool | Scope and use | Qualification |
|---|---|---|
| Operating-system and container process measurements | Shows whole-process or container memory use to compare with JVM reports. | Interpret alongside the limits and measurements of the actual platform. |
| Valgrind | Oracle names it for investigating native leaks on Linux. | Confirm compatibility with the JVM and native libraries in use. |
| Purify | Listed by Oracle as an external investigation tool. | Check current availability and compatibility for the target environment. |
| Windows User-Mode Dump Heap (UMDH) | Listed by Oracle among Windows investigation utilities. | Use only where its platform and target-process requirements are met. |
mtrace and libnjamd |
Linux allocation-tracking utilities named by Oracle. | Verify suitability for the runtime and native stack; JVM-generated code can confuse some native tools. |
| Fatal error log or core dump | Preserves crash evidence for analysis when allocation failure or native-code handling causes a process crash. | Capture and interpret using tools appropriate to the operating system and JVM. |
These are investigation options, not a universal ranking or a guarantee that a tool can attribute every allocation. Check compatibility before relying on a result, especially when the process includes JVM-generated code.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Check system pressure and allocation failure paths
Native allocation failure is not necessarily proof of a leak. Oracle’s Java SE 17 troubleshooting material identifies insufficient swap, another process consuming resources, and a leak in application or API code among the possible causes. Correlate the failure time with process and container limits, system memory and swap conditions, and other resource-consuming processes. If the application crashed, use its fatal error log or core dump to examine what happened at the failure point.
Do these 3 things before closing this tab:
1Clear out junk files and repair common Windows errors2Fix the driver behind crashes, sound loss and screen glitches3Repair Windows errors before they cause bigger problemsBest Value
When a Java heap error is confirmed, size the heap against the effective process or container budget and the needs of native components. When the evidence instead points to native allocation, a larger heap may worsen pressure rather than fix it. Make a configuration change only after identifying which limit or allocation category is implicated.
Quick Recap
A practical decision path
- Capture the failure. Save the complete message and stack trace; note whether the JVM threw an exception, terminated, or crashed. Preserve fatal logs and core dumps when available.
- Classify the message. Separate heap errors from Metaspace or compressed class space errors, native allocation failures, and failures arising in native methods.
- Compare JVM and system views. Record the effective heap and Metaspace limits and compare JVM memory reports with process or container measurements.
- Enable NMT before a reproduction if needed. Restart the target HotSpot process with summary or detail tracking, take a baseline with
jcmd, and compare a later report. - Follow the scope of the evidence. If NMT categories grow, investigate the corresponding HotSpot subsystem. If whole-process memory grows without a corresponding NMT change, investigate JNI, native libraries, CDS-related uncertainty, and system conditions with suitable platform evidence.
- Change the implicated limit or code path. Avoid increasing
-Xmxas a default response to native-memory symptoms; confirm that the change fits the process or container budget and does not displace native memory.
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

