> For the complete documentation index, see [llms.txt](https://docs.rumi.systems/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.rumi.systems/rumi-core/guides/operating-applications/monitoring/memory-statistics.md).

# Memory Statistics

## Overview

Rumi tracks detailed memory usage statistics across several categories: JVM heap and non-heap memory, off-heap memory managed by the platform, native memory allocations, IOBuffer lifecycle, and entity/message/collection object management. These stats are collected by the `MemoryStats` singleton and can be consumed in two ways: via standalone periodic trace output, or as part of container heartbeat messages.

## Configuring Memory Statistics

For complete configuration details including enabling/disabling stats, per-type stats, and standalone trace output, see:

* [Configuring Memory Statistics](/rumi-core/guides/developing-applications/configuring-the-runtime/monitoring/memory-statistics.md) - Complete memory statistics configuration guide

This page focuses on understanding and interpreting the statistics once they are collected.

## Memory Statistics Categories

Memory statistics are collected by the `MemoryStats` singleton and cover four areas:

* **Host Memory** — System-level physical memory, swap, and committed virtual memory
* **Process Memory** — Physical memory footprint of the process (RSS)
* **JVM Memory** — Standard JVM heap and non-heap memory pools (init, used, committed, max)
* **App Memory** — Off-heap (native) memory, IO buffer lifecycle, and ADM entity object management

### Host Memory

Operating system-level memory statistics. When the native runtime is available, these use platform-specific APIs for accuracy; otherwise they fall back to JMX's `OperatingSystemMXBean`.

| Stat                           | Description                                                                                                                                                                                                                                                                                                                                                                                                         |
| ------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **committedVirtualMemorySize** | The amount of virtual memory guaranteed to be available to the process (in bytes).                                                                                                                                                                                                                                                                                                                                  |
| **freePhysicalMemorySize**     | The amount of available physical memory on the system (in bytes). On Linux this reports `MemAvailable` from `/proc/meminfo` (which accounts for reclaimable cache and buffers) rather than raw `MemFree`. On macOS this reports free + inactive pages. On Windows this reports available physical memory. Without the native runtime, falls back to the JMX value which reports `MemFree` on Linux (less accurate). |
| **freeSwapSpaceSize**          | The amount of free swap space (in bytes).                                                                                                                                                                                                                                                                                                                                                                           |
| **totalPhysicalMemorySize**    | The total physical memory on the system (in bytes).                                                                                                                                                                                                                                                                                                                                                                 |
| **totalSwapSpaceSize**         | The total swap space (in bytes).                                                                                                                                                                                                                                                                                                                                                                                    |

### Process Memory

*Since 4.0.619*

| Stat                | Description                                                                                                                                                                                                                                                                                                                            |
| ------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **processRssBytes** | The process RSS (Resident Set Size) in bytes — the actual physical RAM occupied by the process including code, stack, heap, and memory-mapped regions. Collected via native runtime APIs (`/proc/self/stat` on Linux, `mach_task_basic_info` on macOS, `GetProcessMemoryInfo` on Windows). Reports 0 if native support is unavailable. |

### JVM Memory (Heap and Non-Heap)

Standard JVM memory usage as reported by the `MemoryMXBean`:

| Stat                   | Description                                                                                                                              |
| ---------------------- | ---------------------------------------------------------------------------------------------------------------------------------------- |
| **Heap init**          | The amount of heap memory (in bytes) that the JVM initially requested from the operating system. A value of -1 indicates undefined.      |
| **Heap used**          | The current amount of heap memory in use (in bytes).                                                                                     |
| **Heap committed**     | The amount of heap memory (in bytes) guaranteed to be available to the JVM.                                                              |
| **Heap max**           | The maximum amount of heap memory (in bytes) that can be used.                                                                           |
| **Non-Heap init**      | The initial non-heap memory requested (in bytes). Non-heap memory includes the method area, JIT code cache, and internal JVM structures. |
| **Non-Heap used**      | The current amount of non-heap memory in use (in bytes).                                                                                 |
| **Non-Heap committed** | The amount of non-heap memory (in bytes) committed for JVM use.                                                                          |
| **Non-Heap max**       | The maximum amount of non-heap memory (in bytes). A value of 0 indicates undefined.                                                      |

### Off-Heap Memory

Summary statistics for off-heap memory managed by Rumi applications. Off-heap memory is the combination of native memory allocations and IOBuffer memory that is managed outside the JVM heap.

| Stat           | Description                                                                                                                                                |
| -------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **usedLive**   | The total amount of off-heap memory (in bytes) currently in live use by applications. This is the sum of native memory in use plus IOBuffer memory in use. |
| **usedPooled** | The total amount of off-heap memory (in bytes) currently held in pools, available for reuse without new allocation.                                        |

### Native Memory Counters

Counters tracking low-level native memory operations performed by the platform via JNI:

| Stat             | Description                                                                                               |
| ---------------- | --------------------------------------------------------------------------------------------------------- |
| **allocCount**   | The cumulative number of native memory allocation operations performed.                                   |
| **allocBytes**   | The cumulative number of bytes allocated via native memory allocations.                                   |
| **reallocCount** | The cumulative number of native memory reallocation operations performed (resizing existing allocations). |
| **reallocBytes** | The cumulative number of bytes involved in native memory reallocations.                                   |
| **freeCount**    | The cumulative number of native memory free operations performed.                                         |
| **freeBytes**    | The cumulative number of bytes freed via native memory frees.                                             |

The current native memory in use can be derived as: `allocBytes - freeBytes + reallocBytes`.

### IOBuffer Counters

IOBuffers are the platform's primary data transport mechanism. They can be allocated fresh or obtained from a pool, and when no longer needed they are either returned to the pool for reuse or disposed to the garbage collector.

| Stat                       | Description                                                                                                      |
| -------------------------- | ---------------------------------------------------------------------------------------------------------------- |
| **bufferAllocCount**       | The number of IOBuffer creations (new allocations, not from pool).                                               |
| **bufferAllocBytes**       | The cumulative bytes allocated via IOBuffer creations.                                                           |
| **bufferPoolAllocCount**   | The number of IOBuffers obtained from the pool (reused).                                                         |
| **bufferPoolAllocBytes**   | The cumulative bytes obtained via IOBuffer pool allocations.                                                     |
| **bufferReallocCount**     | The number of IOBuffers reallocated due to a size change.                                                        |
| **bufferReallocBytes**     | The cumulative bytes reallocated due to IOBuffer size changes.                                                   |
| **bufferForkCount**        | The number of IOBuffers that were forked (copy-on-write).                                                        |
| **bufferForkBytes**        | The cumulative bytes forked.                                                                                     |
| **bufferGCDisposeCount**   | The number of IOBuffers disposed directly to the garbage collector (not returned to pool).                       |
| **bufferGCDisposeBytes**   | The cumulative bytes disposed directly to the garbage collector.                                                 |
| **bufferPoolDisposeCount** | The number of IOBuffers returned to the pool for reuse.                                                          |
| **bufferPoolDisposeBytes** | The cumulative bytes returned to the IOBuffer pool.                                                              |
| **bufferPoolLeakCount**    | The number of IOBuffers evicted from the pool (for pool size maintenance) and disposed to the garbage collector. |
| **bufferPoolLeakBytes**    | The cumulative bytes evicted from the pool and disposed to the garbage collector.                                |

**Derived values:**

* **Live IOBuffer count**: `bufferAllocCount + bufferPoolAllocCount - bufferPoolDisposeCount - bufferGCDisposeCount`
* **Live IOBuffer bytes**: `bufferAllocBytes + bufferPoolAllocBytes - bufferPoolDisposeBytes - bufferGCDisposeBytes`
* **Pooled IOBuffer count**: `bufferPoolDisposeCount - bufferPoolAllocCount - bufferPoolLeakCount`
* **Pooled IOBuffer bytes**: `bufferPoolDisposeBytes - bufferPoolAllocBytes - bufferPoolLeakBytes`

### Entity Type Counters

Entity type counters track the lifecycle of four categories of objects managed by the platform: **embedded entities**, **state entities**, **messages**, and **collections**. Each category tracks the same set of counters at both an aggregate level and optionally on a per-type basis.

Each object in Rumi is composed of multiple internal components — the entity wrapper, its POJO (Plain Old Java Object) backing, a serializer, a deserializer, metadata, and data buffers. The counters track the lifecycle of each component independently:

#### Entity Wrapper Counters

| Stat                 | Description                                                                                                              |
| -------------------- | ------------------------------------------------------------------------------------------------------------------------ |
| **liveCount**        | The number of entities currently allocated and in use.                                                                   |
| **pooledCount**      | The number of entities currently held in the pool, available for reuse.                                                  |
| **createAllocCount** | The cumulative number of entities created via new allocation (not from pool).                                            |
| **poolAllocCount**   | The cumulative number of entities obtained from the entity pool (reused).                                                |
| **GCDisposeCount**   | The cumulative number of entities that were not properly disposed and were released to the garbage collector.            |
| **poolDisposeCount** | The cumulative number of entities returned to the pool via `dispose()`.                                                  |
| **poolLeakCount**    | The cumulative number of entities evicted from the pool for pool size maintenance and released to the garbage collector. |

#### POJO Counters

The POJO is the Java object backing an entity's fields. Each entity wrapper references a POJO. The same counter structure applies:

| Stat                     | Description                                                       |
| ------------------------ | ----------------------------------------------------------------- |
| **pojoLiveCount**        | The number of POJO objects currently allocated and in use.        |
| **pojoPooledCount**      | The number of POJO objects currently held in the pool.            |
| **pojoCreateAllocCount** | The cumulative number of POJOs created via new allocation.        |
| **pojoPoolAllocCount**   | The cumulative number of POJOs obtained from the pool.            |
| **pojoGCDisposeCount**   | The cumulative number of POJOs disposed to the garbage collector. |
| **pojoPoolDisposeCount** | The cumulative number of POJOs returned to the pool.              |
| **pojoPoolLeakCount**    | The cumulative number of POJOs evicted from the pool.             |

#### Serializer and Deserializer Counters

Serializers and deserializers are used when encoding/decoding entities for transport or persistence. Each has the same counter structure:

| Stat                                                              | Description                                       |
| ----------------------------------------------------------------- | ------------------------------------------------- |
| **serializerLiveCount** / **deserializerLiveCount**               | Live serializers/deserializers currently in use.  |
| **serializerPooledCount** / **deserializerPooledCount**           | Serializers/deserializers currently held in pool. |
| **serializerCreateAllocCount** / **deserializerCreateAllocCount** | Cumulative new allocations.                       |
| **serializerPoolAllocCount** / **deserializerPoolAllocCount**     | Cumulative pool allocations.                      |
| **serializerGCDisposeCount** / **deserializerGCDisposeCount**     | Cumulative GC disposals.                          |
| **serializerPoolDisposeCount** / **deserializerPoolDisposeCount** | Cumulative pool disposals.                        |
| **serializerPoolLeakCount** / **deserializerPoolLeakCount**       | Cumulative pool evictions.                        |

#### Metadata and Data Buffer Counters

Metadata and data buffers hold the serialized representation of entity fields:

| Stat                         | Description                                                    |
| ---------------------------- | -------------------------------------------------------------- |
| **metadataLiveCount**        | The number of metadata objects currently in use.               |
| **metadataLiveBytes**        | The bytes held by live metadata objects.                       |
| **metadataAllocCount**       | The cumulative number of metadata objects allocated.           |
| **metadataAllocBytes**       | The cumulative bytes allocated for metadata.                   |
| **metadataGCDisposeCount**   | The cumulative number of metadata objects disposed to GC.      |
| **metadataGCDisposeBytes**   | The cumulative bytes of metadata disposed to GC.               |
| **metadataPoolDisposeCount** | The cumulative number of metadata objects returned to pool.    |
| **metadataPoolDisposeBytes** | The cumulative bytes of metadata returned to pool.             |
| **dataLiveCount**            | The number of data buffer objects currently in use.            |
| **dataLiveBytes**            | The bytes held by live data buffers.                           |
| **dataAllocCount**           | The cumulative number of data buffer objects allocated.        |
| **dataAllocBytes**           | The cumulative bytes allocated for data buffers.               |
| **dataGCDisposeCount**       | The cumulative number of data buffer objects disposed to GC.   |
| **dataGCDisposeBytes**       | The cumulative bytes of data buffers disposed to GC.           |
| **dataPoolDisposeCount**     | The cumulative number of data buffer objects returned to pool. |
| **dataPoolDisposeBytes**     | The cumulative bytes of data buffers returned to pool.         |

## Standalone Trace Output Format

The standalone memory stats trace output contains the following sections:

Sample output:

```
Host {101,455,667,200, 89,800,000,000}
Process {1,073,741,824}
Heap {96,468,992, 60,817,408, 99,614,720, 1,431,830,528}
OffHeap {12,582,912, 8,388,608[16,777,216, 4,194,304, 0, 8,388,608, 4,194,304, 8,388,608, 0]}
IOBuf {1,250, 500[8,388,608, 3,145,728]}
Message Entities {10, 5 Po {10, 5} Se {10, 5} De {10, 5} Me {1,024} Da {4,096}}
Embedded Entities {0, 0 Po {0, 0} Se {0, 0} De {0, 0} Me {0} Da {0}}
State Entities {100, 25 Po {100, 25} Se {0, 0} De {0, 0} Me {16,384} Da {65,536}}
State Collections {50, 10 Po {50, 10} Se {0, 0} De {0, 0} Me {8,192} Da {32,768}}
```

The format uses locale-specific number formatting with all values in raw bytes.

**Interpreting the output:**

* **Host**: Total physical memory and available memory in bytes. Available memory is `MemAvailable` on Linux (includes reclaimable cache/buffers), free + inactive on macOS, available physical on Windows. Falls back to JMX values without native runtime. *(Since 4.0.619)*
* **Process**: Process-level memory metrics. Currently reports RSS (Resident Set Size) in bytes. Reports 0 if native runtime is unavailable. *(Since 4.0.619)*
* **Heap**: JVM heap memory in bytes — initial, used, committed, and max.
* **OffHeap**: Total off-heap memory summary. `usedLive` is memory in active use; `usedPooled` is memory held in pools. The bracketed values break down the raw counters contributing to these totals.
* **IOBuf**: IOBuffer count (live and pooled) with corresponding byte totals in brackets.
* **Entity sections** (Message Entities, Embedded Entities, State Entities, State Collections): Each shows aggregate live/pooled counts for the entity wrapper, then sub-sections for POJOs (`Po`), Serializers (`Se`), Deserializers (`De`), Metadata bytes (`Me`), and Data bytes (`Da`).

When per-type stats are enabled (`nv.stats.memory.type.enable=true`), each entity section is followed by per-class breakdowns prefixed with `...`:

```
Message Entities {10, 5 Po {10, 5} Se {10, 5} De {10, 5} Me {1,024} Da {4,096}}
...com.example.MyMessage {8, 4 Po {8, 4} Se {8, 4} De {8, 4} Me {800} Da {3,200}}
...com.example.MyOtherMessage {2, 1 Po {2, 1} Se {2, 1} De {2, 1} Me {224} Da {896}}
```

## Related Topics

* [Configuring Memory Statistics](/rumi-core/guides/developing-applications/configuring-the-runtime/monitoring/memory-statistics.md) - Enable/disable stats, configure per-type stats and standalone trace
* [Container Heartbeats](/rumi-core/guides/operating-applications/monitoring/container-heartbeats.md) - How memory stats appear in container heartbeats
* [Coding for Zero Garbage](/rumi-core/guides/developing-applications/authoring-user-code/message-processing/processing-messages/handling-messages/coding-for-zero-garbage.md) - Techniques for zero-garbage operation
* [Tuning Pools](/rumi-core/guides/developing-applications/authoring-user-code/message-processing/processing-messages/handling-messages/coding-for-zero-garbage/tuning-pools.md) - Pool configuration and tuning
* [Trace Logging](/rumi-core/guides/operating-applications/analysis-and-troubleshooting/trace-logging.md) - General trace logging configuration
