[id='jvm-heap-memory-allocation_{context}']
= JVM heap space allocation

Determine the volume of memory that you require for your {brandname} deployment, so that you have enough data storage capacity to meet your needs.

[IMPORTANT]
====
Allocating a large memory heap size in combination with setting garbage collection (GC) times might impact the performance of your {brandname} deployment in the following ways:

* If a JVM handles only one thread, the GC might block the thread and reduce the JVM’s performance. The GC might operate ahead of the deployment. This asynchronous behavior might cause large GC pauses.
* If CPU resources are low and GC operates synchronously with the deployment, GC might require more frequent runs that can degrade your deployment’s performance.
====

The following table outlines two examples of allocating JVM heap space for data storage. These examples represent safe estimates for deploying a cluster.

[%autowidth,cols="1,1",stripes=even,%noheader]
|===
|Cache operations only, such as read, write, and delete operations.
|Allocate **50%** of JVM heap space for data storage

|Cache operations and data processing, such as queries and cache event listeners.
|Allocate **33%** of JVM heap space for data storage
|===

[NOTE]
====
Depending on pattern changes and usage for data storage, you might consider setting a different percentage for JVM heap space than any of the suggested safe estimates.

Consider setting a safe estimate before you start your {brandname} deployment. After you start your deployment, check the performance of your JVM and the occupancy of heap space. You might need to re-adjust JVM heap space when data usage and throughput for your JVM significantly increases.
====

The safe estimates were calculated on the assumption that the following common operations were running inside a JVM. The list is not exhaustive, and you might set one of these safe estimates with the purpose of performing additional operations.

* {brandname} converts objects in serialized form to key-value pairs. {brandname} adds the pairs to caches and persistent storage.
* {brandname} encrypts and decrypts caches from remote connections to clients.
* {brandname} performs regular querying of caches to collect data.
* {brandname} strategically divides data into segments to ensure efficient distribution of data among clusters, even during a state transfer operation.
* GC performs more frequent garbage collections, because the JVM allocated large volumes of memory for GC operations.
* GC dynamically manages and monitors data objects in JVM heap space to ensure safe removal of unused objects.

Consider the following factors when allocating JVM heap space for data storage, and when determining the volume of memory and CPU requirements for your {brandname} deployment:

* Clustered cache mode.
* Number of segments.
** For example, a low number of segments might affect how a server distributes data among nodes.
* Read or write operations.
* Rebalancing requirements.
** For example, a high number of threads might quickly run in parallel during a state transfer, but each thread operation might use more memory.
* Scaling clusters.
* Synchronous or asynchronous replication.

Most notable {brandname} operations that require high CPU resources include rebalancing nodes after pod restarts, running indexing queries on data, and performing GC operations.

.Off-heap storage

{brandname} uses JVM heap representations of objects to process read and write operations on caches or perform other operations, such as a state transfer operation. You must always allocate some JVM heap space to {brandname}, even if you store entries in off-heap memory.

The volume of JVM heap memory that {brandname} uses with off-heap storage is much smaller when compared with storing data in the JVM heap space. The JVM heap memory requirements for off-heap storage scales with the number of concurrent operations as against the number of stored entries.

{brandname} uses topology caches to provide clients with a cluster view.

If you receive any `OutOfMemoryError` exceptions from your {brandname} cluster, consider the options:

* Disable the state transfer operation, which might results in data loss if a node joins or leaves a cluster.
* Recalculate the JVM heap space by factoring in the key size and the number of nodes and segments.
* Use more nodes to better manage memory consumption for your cluster.
* Use a single node, because this might use less memory. However, consider the impact if you want to scale your cluster to its original size.