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.