直接修改jvm.options中-Xms和-Xmx为相同值(如-Xms512m -Xmx512m),确保不超物理内存50%、单位小写、无空格;同时需调高ulimit -u和vm.max_map_count,并确认目录权限与进程用户一致。

直接改 jvm.options 是最稳的路
宝塔面板下,ES_HEAP_SIZE 环境变量基本不可靠——计划任务、守护进程、重启后都可能失效。唯一能确保生效的方式,是直接编辑 /www/server/es-search/config/jvm.options(路径以你实际安装位置为准)。
打开文件后,找到类似这样的两行(通常在第 20–30 行):
-Xms1g -Xmx1g
改成一致且符合你机器实际的值,例如 2GB 总内存的服务器,建议设为:
-Xms512m -Xmx512m
- 单位必须小写:
m或g,M/G会报错 - 不能带空格:
-Xms 512m是非法语法,ES 启动直接失败 -
-Xms和-Xmx必须相等,否则 GC 频繁、延迟飙升 - ≤2GB 物理内存 →
-Xmx512m;≤4GB → 最高设-Xmx1g
启动报 unable to create native threads?不是堆内存的事
改完 jvm.options 还起不来,错误日志里出现 unable to create native threads 或 memory limit exceeded,这大概率是系统级限制没放开,和 JVM 堆无关。
- 查当前线程上限:
ulimit -u,低配云服务器常是 1024,不够 ES 启动 - 临时调高:
ulimit -u 65535 - 查 mmap 区域限制:
sysctl vm.max_map_count,ES 要求 ≥262144 - 临时生效:
sysctl -w vm.max_map_count=262144;持久化要追加到/etc/sysctl.conf - 检查
path.logs和path.data目录权限:必须属于运行 ES 的用户(如www),否则 JVM 初始化阶段就静默退出,日志里看不到堆相关提示
别信“设大点更爽”,32GB 是硬红线
哪怕你有 64GB 物理内存,也不要给单节点 ES 设 -Xmx32g 以上。JVM 在 >32GB 时会关闭压缩普通对象指针(Compressed OOPs),指针从 4 字节涨到 8 字节,实际可用堆反而缩水,GC 压力指数上升。
- 物理内存 ≤8GB → 堆设
2g~4g,留一半给 Lucene 文件缓存 - 物理内存 16GB → 堆最多
8g,再大收益递减甚至负向 - 真要大内存,用多节点部署,而不是堆大单节点
- 确认是否启用了
bootstrap.memory_lock: true:它要求系统允许锁住内存,需配套配置/etc/security/limits.conf中的memlock项
堆没超但内存还是爆?查 fielddata 和 doc_values
ES 内存占用 ≠ JVM 堆大小。堆外内存(比如 fielddata)同样致命,尤其对 text 字段做聚合或排序时,会把全部词项加载进堆,几十万文档就能吃光 2GB。
- 禁用不需要聚合的
text字段:"fielddata": false - 需要聚合的字段(如状态、标签、ID)必须用
keyword类型,依赖doc_values(磁盘存储 + OS Page Cache 加速) - 查当前 fielddata 占用:
GET /_nodes/stats/indices/fielddata?fields=* - 限制全局 fielddata 缓存:
indices.fielddata.cache.size: 20%(写入elasticsearch.yml)
堆参数只是第一道门,真正压垮低配机器的,往往是 mapping 设计和查询方式——这些不会在 jvm.options 里体现,但会在日志里留下 OutOfMemoryError: Java heap space 的痕迹。


















