问题现象
今天安装Elasticsearch 5.6.3,在启动ES后台服务时,日志显示JVM报出Cannot allocate memory错误。
JDK版本:jdk-8u261-linux-x64
问题分析
内存不足?
网上查询,大多都是说内存不足或swap空间不足,所以jvm无法申请内存。
free -h查看内存,发现空闲内存还有3.7G,申请的内存只有600多M,肯定不是内存不足的问题。另外虚机没有配置swap空间,swap为0。有文章说jvm会根据swap剩余空间,来决定内存是否能申请成功。这倒有可能是一个因素,但应该不是主要原因,继续找答案。。。
JDK问题?
中间想到过是不是JDK问题,但想想可能性极小,放在最后考虑,先继续找答案。。。
然后,找到了这么一篇文章:Cannot allocate memory 的分析及解决方法
成功解决了问题!
以下会介绍解决问题的过程,并附上分析,可以直接往下看,无需看原文。当然,对某些问题之外的细节感兴趣的,可以看看原文,讲的比较细致。
解决过程
1.像上面所说既然是内存申请失败,首先查看内存是否不足。
free -h
发现空闲内存有3.7G,排除问题。
2.查看是否为进程过多
查看服务器最大进程数,数量3w+
sysctl kernel.pid_max
查看当前进程数,数量为几百,排除问题。
ps -eLf | wc -l
3.查看磁盘是否写满
磁盘也没满,排除问题
df -h
4.查看linux内核参数overcommit_memory
Linux下有个内核参数overcommit_memory,是内存分配策略,程序在启动的时候会先去申请内存,尽管不一定都会用的到那么多。此参数决定是否接受超大内存请求的条件。这个参数有三个可能的值:
0:默认设置。内核执行启发式内存过量使用处理,方法是估算可用内存量,并拒绝明显无效的请求。遗憾的是因为内存是使用启发式而非准确算法计算进行部署,这个设置有时可能会造成系统中的可用内存超载。
1:内核执行无内存过量使用处理。使用这个设置会增大内存超载的可能性,但也可以增强大量使用内存任务的性能。
2:内存拒绝等于或者大于总可用 swap 大小以及overcommit_ratio指定的物理RAM比例的内存请求。如果您希望减小内存过度使用的风险,这个设置就是最好的。
cat /proc/sys/vm/overcommit_memory
发现值为2!
查看可申请内存总量和已提交内存数,发现剩余很少。
cat /proc/meminfo | grep Commit
这应该是问题所在了!
解决问题:
接下来,修改overcommit_memory的值
vim /etc/sysctl.conf
发现文件中该参数的值为2,把它修改为2
vm.overcommit_memory=1
使配置生效
sysctl -p
再启动ES后台,成功启动,问题解决!