Using NetBeans to profile memory with VisualVM

A Java application can appear stable during a short test in NetBeans and still consume steadily more heap during a full working day. VisualVM helps turn that suspicion into evidence by showing heap capacity, used memory, garbage-collection activity, threads and object samples while the program runs. Used alongside NetBeans, it creates a practical workflow for diagnosing leaks before they reach production.

This approach suits desktop applications, web services and Java EE projects developed on Windows, macOS or Linux. It is also useful for Australian teams working across Sydney, Melbourne, Brisbane and Perth, where different time zones and production schedules make repeatable, low-disruption diagnostics especially valuable.

Approach Best use Main limitation
VisualVM Monitor Quick heap and GC overview Limited object-level detail
VisualVM Sampler Finding classes consuming memory Sampling can miss short-lived allocations
Heap dump analysis Investigating retained objects The dump may be large and sensitive
NetBeans Profiler Detailed allocation and CPU profiling More setup and runtime overhead

Prepare the NetBeans project

Start with a reproducible scenario. Open the Maven or Gradle project in NetBeans, select the intended JDK under the project properties, and run the application with the same configuration used for testing. Record the action that causes growth, such as importing a large CSV file, opening many Swing windows or processing a batch of messages.

For a broader tour of NetBeans features and tutorials, the site’s category archive provides useful background alongside profiling material. Keep the IDE and VisualVM compatible with the selected Java release; a current JDK normally includes the monitoring interfaces VisualVM needs, while older or vendor-specific installations may require an explicit JMX connection.

Before profiling, close unrelated Java programs. This makes the process list easier to read and prevents attaching to the wrong JVM. On a developer laptop in Melbourne or Adelaide, it is also sensible to run a repeatable test while the machine is connected to power, since thermal throttling and battery-saving modes can affect timings.

Connect VisualVM to the running JVM

Launch VisualVM separately from NetBeans, then look under Local in the Applications panel. A program started from the IDE should normally appear by its process identifier. Select it to view the Monitor tab, where heap usage, metaspace, loaded classes and threads are displayed in real time.

If the process is missing, check that NetBeans and VisualVM use compatible permissions and Java installations. On some systems, starting one application with elevated privileges prevents another user-level tool from discovering it. For a remote server, enable JMX only with suitable authentication, firewall rules and transport protection; exposing an unauthorised monitoring port is an avoidable security risk.

The Monitor view is useful for identifying patterns. A healthy workload usually shows memory rising and then falling after garbage collection. If the baseline climbs after each cycle, retained objects may be accumulating. A high heap percentage alone is not proof of a leak, because the JVM is designed to use available memory before collecting it.

Capture useful evidence

Use the Sampler tab to inspect live classes and their estimated heap contribution. Run the business operation several times, allow garbage collection between repetitions where practical, and compare the dominant classes. A growing collection, cache entry, listener or session object is more meaningful than a single large allocation during startup.

A heap dump provides a deeper snapshot. Capture one after the application reaches its normal idle state and another after the suspected operation has been repeated. VisualVM can display class counts and retained sizes, helping identify which object keeps a chain of other objects reachable. Compare dumps rather than relying on one image of the heap.

Heap dumps can contain customer names, email addresses, request payloads and authentication-related values. Under Australia’s Privacy Act 1988 and the Australian Privacy Principles, treat these files as sensitive diagnostic material. Store them in approved locations, restrict access, remove them after analysis and avoid copying production data to a personal workstation or an unmanaged cloud drive.

Interpret garbage collection and retention

A frequent mistake is to blame the garbage collector when the application has a retention problem. GC pauses may become longer as the live set expands, but collection cannot remove objects that are still referenced. Examine paths to GC roots in the dump, paying attention to static fields, executor queues, thread-local values, application caches and event listeners that were never deregistered.

Compare memory after a full user journey, not just after application startup. For example, a Java desktop tool used by a Brisbane office may open and close hundreds of customer records during a shift. If each view leaves behind a listener or cached model, the leak becomes visible only after realistic repetition.

For server-side systems, correlate VisualVM observations with request rates, message queues and database activity. A message-driven bean that retains a payload, or an EJB that stores request-specific state in a long-lived object, can create a gradual rise in old-generation usage. GC logs and application logs add timing context that a screenshot cannot provide.

Build a repeatable profiling routine

Keep profiling separate from performance claims. VisualVM’s sampler and heap-dump operations introduce overhead, and a test run from NetBeans may not represent a production deployment with different JVM flags, container settings or traffic. Use a staging environment that resembles the target system, then confirm the suspected fix with the same workload and measurement points.

NetBeans can remain the control centre for editing, rebuilding and rerunning the application, while VisualVM provides the live JVM view. If the project includes a Swing interface, related NetBeans customisation work, such as custom palette setup, can make test screens easier to construct and repeat consistently.

Save concise notes with each run: Java version, operating system, heap flags, test duration, action count and the time of every dump. Use Australian Eastern, Central or Western time consistently when several locations share the investigation. Teams supporting local retail, banking or healthcare software can then compare results across Sydney, Perth and remote workers without confusing clock differences.

A disciplined cycle—reproduce, monitor, capture, compare and retest—usually reveals whether memory growth comes from normal JVM behaviour, an oversized cache or objects that should have been released. It also gives developers evidence they can act on before a heap exhaustion error affects users.