生产 Elasticsearch 出现 OutOfMemoryError: Java heap space 时,调整堆大小是一条排查路径,但不能只看进程还能否重新启动。错误中的查询参数,也可能暴露出持续消耗内存的请求模式。
日志里不只有 OOM
当时日志包含 from[12700000],size[100000]。这类深分页加大批量返回,会要求搜索过程处理大量候选结果;即使请求发生在夜间,也不能排除后台任务或重试持续触发它。
因此需要同时记录请求来源、并发、分片和排序方式,再观察 JVM 堆、GC 与查询负载,不能凭报错时间判断查询没有问题。
确认设置是否真的生效
旧版 1.x、2.x 环境曾通过 ES_HEAP_SIZE 设置堆,后续版本采用不同的 JVM 配置机制,并可能自动计算堆大小。应查看实际启动参数和节点统计,而不是只修改一个文件就认为运行值已经改变。
GET /_nodes/stats/jvm
检查 heap_used、heap_max 和 GC 等字段。节点、容器和操作系统的内存限制也要一起看:除了 Java 堆,还需要给文件缓存和其他本地内存留出空间。配置值要依据对应版本官方建议和实际测量,不应一味调大。
改查询,才能减少重复故障
交互查询限制页深和每页数量;批量导出按版本使用 scroll 或 PIT 配合 search_after 等适合的机制,并及时释放上下文。它们的语义和资源成本不同,不能只把 from 改成另一种参数就结束。
同时检查聚合桶数、排序字段、字段映射和客户端超时后的重试。一次大请求被多次重试,可能让原本的资源压力持续放大。
调整后用相同样本验证结果与资源变化,观察一段完整业务周期。能在更小的资源预算内稳定完成任务,比单纯延后下一次 OOM 更有意义。