Apache Ignite:堆外内存驱逐策略不生效引发内存溢出异常
Ignite 2.15配置RANDOM_2_LRU驱逐仍报IgniteOutOfMemoryException的原因及解决
核心问题
配置的RANDOM_2_LRU驱逐策略未实际生效,导致目标数据区(SAMPLE_TEST,maxSize=60MiB)被填满后无法自动清理,最终触发内存溢出。
驱逐策略未生效的具体原因
- 缓存未关联目标DataRegion:仅配置DataRegion的驱逐策略,但缓存未通过
setDataRegionName("SAMPLE_TEST")指定使用该区域,缓存会默认使用无驱逐配置的默认数据区,自然无法触发驱逐。 - 驱逐触发条件未满足:
RANDOM_2_LRU仅在数据区使用率达到evictionThreshold(默认0.9,即90%)且有新数据写入时才会触发,不会后台主动清理。如果数据量直接超过60MiB,且未达到阈值前就填满内存,驱逐不会启动。- 驱逐仅针对堆外内存,若缓存配置强制使用堆内内存(如错误设置
MemoryMode.ONHEAP),DataRegion的堆外驱逐策略完全无效。
- 驱逐参数配置缺失或不合理:
- 未显式设置
evictionThreshold,或设置值过高(如0.99),导致内存接近耗尽才触发驱逐,来不及清理。 RANDOM_2_LRU需要页面访问跟踪支持,若禁用了数据区的指标收集(metricsEnabled=false),会导致策略无法正常工作。
- 未显式设置
- 写入速度远超驱逐效率:即使驱逐生效,若数据写入速度远快于页面驱逐速度,内存仍会被快速填满。
排查与解决步骤
- 验证缓存与DataRegion的关联:检查缓存配置代码,确保调用了
cacheCfg.setDataRegionName("SAMPLE_TEST"),将缓存绑定到配置了驱逐策略的数据区。 - 调整驱逐触发参数:
- 显式设置合理的
evictionThreshold(建议0.8-0.9),示例代码:DataRegionConfiguration regionCfg = new DataRegionConfiguration(); regionCfg.setName("SAMPLE_TEST"); regionCfg.setMaxSize(60 * 1024 * 1024); regionCfg.setPageEvictionMode(PageEvictionMode.RANDOM_2_LRU); regionCfg.setEvictionThreshold(0.85); // 显式设置阈值 - 确保缓存使用堆外内存模式(默认
MemoryMode.OFFHEAP_TIERED即可,无需强制设为堆内)。
- 显式设置合理的
- 启用指标收集:确认DataRegion的
metricsEnabled=true(默认开启),保证Ignite能跟踪页面访问情况,支持RANDOM_2_LRU策略。 - 评估内存与数据量匹配度:若业务数据量持续超过60MiB,即使驱逐生效也无法覆盖,需调大
maxSize或启用持久化(persistenceEnabled=true)。 - 监控驱逐行为:通过Ignite控制台或JMX查看数据区的
evictedPagesCount指标,确认驱逐是否实际触发。若指标为0,说明配置未生效或触发条件未满足。
内容的提问来源于stack exchange,提问作者Victor
相关产品推荐
相关产品推荐

