Heap Usage Monitoring

Introduction

When building a Standalone Application, the Java heap size must be specified as an Application Option (see Option(text): Java heap size (in bytes)). The value to set in this option depends on the maximum heap usage, and the developer can estimate it by running the application.

The MicroEJ Core Engine provides a Java API to introspect the heap usage at runtime. Additionally, heap usage monitoring can be enabled to compute the maximum heap usage automatically.

Here are the descriptions of the different notions related to heap usage:

  • Heap: memory area used to store the objects allocated by the application.
  • Heap Size: current size of the heap.
  • Maximum Heap Size: maximum size of the heap. The heap size cannot exceed this value. See Option(text): Java heap size (in bytes).
  • Heap Usage: the amount of the heap currently being used to store alive objects.
  • Garbage Collector (GC): a memory manager in charge of recycling unused objects to increase free memory.
Heap Structure Summary

Heap Structure Summary

The Java class java.lang.Runtime defines the following methods:

  • gc(): Runs the garbage collector. System.gc() is an alternative means of invoking this method.
  • freeMemory(): Returns the amount of free memory in the heap. This value does not include unused objects eligible for garbage collection. Calling the gc() method may result in increasing the value returned by this method.
  • totalMemory(): Returns the current size of the heap. The value returned by this method may vary over time.
  • maxMemory(): Returns the maximum size of the heap.

Heap Usage Introspection

The methods provided by the Runtime class allow introspecting the heap usage by comparing the heap size and the free memory size. A garbage collection must be executed before computing the heap usage to recycle all the unused objects and count only alive objects.

The application can compute the current heap usage by executing the following code:

Runtime runtime = Runtime.getRuntime(); // get Runtime instance
runtime.gc(); // Ensure unused objects are recycled
long heapUsage = runtime.totalMemory() - runtime.freeMemory();

This example gives the heap usage at a given point but not the maximum heap usage of the application.

Note

When heap usage monitoring is disabled, the heap size is fixed, and so totalMemory() and maxMemory() return the same value.

Automatic Heap Usage Monitoring

The maximum heap usage of an application’s execution can be computed automatically by enabling heap usage monitoring.

Note

This feature is available in the MicroEJ Architecture versions 7.16.0 or higher.

When this option is activated, an initial size for the heap must be specified, and the MicroEJ Core Engine increases the heap size dynamically. The value returned by totalMemory() is the current heap size. maxMemory() returns the maximum size of the heap. A call to gc() decreases the heap size to the higher value of either the heap usage or the initial heap size.

At any moment, totalMemory() returns the maximum heap usage of the current execution (assuming the maximum heap usage is higher than the initial heap size, and gc() has not been called).

See the section Option(checkbox): Enable Java heap usage monitoring to enable this option and configure the initial heap size.

Even if the heap size can vary during time, a memory section of maxMemory() bytes is allocated at link time or during the MicroEJ Core Engine startup. No dynamic allocation is performed when increasing the heap size.

Warning

A small initial heap size will impact the performances as the GC will be executed every time the heap size needs to be increased.

Furthermore, the smaller the heap size is, the more frequent the GC will occur. This feature should be used only for heap usage benchmarking.

Heap Usage Analysis

To analyze heap usage and see what objects are alive in the application, use the Heap Dumper & Heap Analyzer tools.