Map eviction - hazelcast/hazelcast-scala GitHub Wiki

By default the IMap, like a regular java.util.Map, will eventually run out of memory if entries are continuously added. To avoid that, eviction should be enabled.

Normal Java heap memory

Java heap memory is the default storage.

By entry count

Eviction by entry count works for both in-memory formats BINARY and OBJECT.

Note that, when using entry count eviction, there's no guarantee that an exceptional large value can't still lead to an OOME. Size is not considered, only number of entries. If the values are of similar size, this works well. If not, consider using memory based eviction.

Per node

This configuration will ensure a maximum of 10,000 entries per Hazelcast node, and when reached, will evict using LRU policy:

val conf = new Config
conf.getMapConfig("myMap")
  .setMaxSizeConfig(PerNode(10000))
  .setEvictionPolicy(EvictionPolicy.LRU)

Per partition

This configuration will ensure a maximum of 500 entries per partition, and when reached, will evict using LRU policy (by default Hazelcast uses 271 partitions, spread evenly among available nodes):

val conf = new Config
conf.getMapConfig("myMap")
  .setMaxSizeConfig(PerPartition(500))
  .setEvictionPolicy(EvictionPolicy.LRU)

Note that the entry count limits for both PerNode and PerPartition are not exact, but approximate.

By memory usage

When using memory based eviction, only in-memory format BINARY is supported (default).

By map heap usage (absolute)

This configuration will ensure that the configured map will only use, at most, 500MB of heap memory, and when reached, will evict using LRU policy:

val conf = new Config
conf.getMapConfig("myMap")
  .setInMemoryFormat(InMemoryFormat.BINARY)
  .setMaxSizeConfig(UsedHeapSize(500.megabytes))
  .setEvictionPolicy(EvictionPolicy.LRU)

By map heap usage (relative)

This configuration will ensure that the configured map will only use, at most, 80% of allocated heap memory, and when reached, will evict using LRU policy:

val conf = new Config
conf.getMapConfig("myMap")
  .setInMemoryFormat(InMemoryFormat.BINARY)
  .setMaxSizeConfig(UsedHeapPercentage(80))
  .setEvictionPolicy(EvictionPolicy.LRU)

NOTICE: When using heap usage as eviction trigger, remember that multiple maps are additive. So two maps using 500MB will be allowed to use 1GB combined. Same for percentage based triggering. Two maps configured for 80% heap, will be allowed to use 160% of available heap, eventually leading to OOME.

By free memory

To avoid the additive behavior of heap usage per map, instead eviction can be based on JVM free memory. Unlike heap usage, any in-memory format will work, BINARY and OBJECT.

By free memory (absolute)

This configuration will ensure that eviction is triggered when then JVM reaches 400MB remaining free memory, and when reached, will evict using LRU policy:

val conf = new Config
conf.getMapConfig("myMap")
  .setMaxSizeConfig(FreeHeapSize(400.megabytes))
  .setEvictionPolicy(EvictionPolicy.LRU)

By free memory (relative)

This configuration will ensure that eviction is triggered when there's 15% left of allocated JVM heap memory, and when reached, will evict using LRU policy:

val conf = new Config
conf.getMapConfig("myMap")
  .setMaxSizeConfig(FreeHeapPercentage(15))
  .setEvictionPolicy(EvictionPolicy.LRU)

Enterprise High Density (native) memory

High Density is an Enterprise feature of Hazelcast that allows storing IMap entries off-heap, allowing very large maps with zero GC impact.

To enable, configure the amount of memory to allocate for Hazelcast:

conf.getNativeMemoryConfig
  .setEnabled(true)
  .setSize(64.gigabytes)

To enable High Density for IMap, use in-memory format NATIVE.

Unlike the heap-based eviction, the High Density eviction uses a sampling eviction algorithm, thus setting an eviction percentage is not required (or possible).

By memory usage

Just like for heap-based memory usage, native memory usage is additive, per map.

By memory usage (absolute)

This configuration will ensure that the configured map will only use, at most, 10GB of native memory:

val conf = new Config
conf.getMapConfig("myMap")
  .setInMemoryFormat(InMemoryFormat.NATIVE)
  .setMaxSizeConfig(UsedNativeMemorySize(10.gigabytes))
  .setEvictionPolicy(EvictionPolicy.LRU)

By memory usage (relative)

This configuration will ensure that the configured map will only use, at most, 80% of allocated native memory:

val conf = new Config
conf.getMapConfig("myMap")
  .setInMemoryFormat(InMemoryFormat.NATIVE)
  .setMaxSizeConfig(UsedNativeMemoryPercentage(80))
  .setEvictionPolicy(EvictionPolicy.LRU)

By free memory

Like for heap memory, eviction can be based on remaining free native memory.

By free memory (absolute)

This configuration will ensure that eviction is triggered when remaining native memory reaches 5GB:

val conf = new Config
conf.getMapConfig("myMap")
  .setInMemoryFormat(InMemoryFormat.NATIVE)
  .setMaxSizeConfig(FreeNativeMemorySize(5.gigabytes))
  .setEvictionPolicy(EvictionPolicy.LRU)

By free memory (relative)

This configuration will ensure that eviction is triggered when there's 15% left of allocated native memory:

val conf = new Config
conf.getMapConfig("myMap")
  .setInMemoryFormat(InMemoryFormat.NATIVE)
  .setMaxSizeConfig(FreeNativeMemoryPercentage(15))
  .setEvictionPolicy(EvictionPolicy.LRU)

By entry count

Just like for JVM heap memory, NATIVE allocation supports eviction by entry count. However, because the eviction algorithm is different, setEvictionPercentage has no effect.