最近在看一个Kibana查询ES超时的问题,在gc.log中有一定比例的内存分配失败的情况。
默认情况下JVM按照1:2的比例将xmx
设定的内容进行分配,例如1
-XX:Xmx=16g
该例子中将JVM的堆内容设置为16G,那么新生代为16✖️1➗3 = 5G内存,老生代16✖️2➗3=11G内存,其中新生代的4 of 5的部分也就是5✖️4➗5=4G分给伊甸园区,S区剩余的新生代内存为1G。
但是,由于ES在默认指定的老年代(CMS)+ 新生代(ParNew)收集器。
如果没有显示设置新生代大小,JVM 在使用 CMS 收集器时会自动调参,新生代的大小在没有设置的情况下是通过计算得出的。
从gc.log中可以得出:
图中EDEN为笔误,应为新生代。
10833056/613440 ~= 21 也就是说老年代比上新生代不是默认的2:1,而是21:1,老年代是10G,而新生代是0.5G。
因此需要重新配置下ES的JVM参数:
1 | -XX:NewRatio=2 -XX:SurvivorRatio=8 |
将老生代与新生代的比例严格限定为2:1,伊甸园区的比例为严格的8/10部分。