JVM调优之服务内存超过阈值报警

今早收到一条短信,具体报警信息以下:算法

【UMP JVM监控内存报警】应用名:发券worker(jdos_couponwkr);KEY【coupon.send.worker.jvm】,主机名:【host-10-183-72-114】,实例【11909223645】的堆内存使用率连续3次超过设定阀值【90.0%】。报警级别:【Warning】,报警时间:【2019-07-17 07:36:12】。docker

说是有一台机器的堆内存使用超过阈值90%。这条短信虽然言简意赅,可是背后隐藏的技术细节,我这里来陈述一下,谬误之处,还请指教。jvm

初看此报警,则知道堆内存使用超过阈值了。第一反应通常都是把堆内内存调大,就好了。可是事实真的如此吗?不妨来一块儿看看。blog

假设咱们如今堆内内存为1G,则堆内存使用曲线以下:内存

image

能够看到总体使用正常,回收正常,很是平稳。资源

如今,咱们把堆内内存调整为2G,则堆内内存使用曲线以下:get

image

能够看到,堆内内存使用率依然超过90%,说明单纯的调节堆内内存的大小,是没法解决此问题的。it

为何呢? 因为jvm工做的时候,对堆内内存的使用是自适应的,你给的多,它用的多,你给的少,它用的少。因此这也是为啥你给它1G大小,它能将堆内存用的超过90%,你给他2G大小,他也能将堆内存用的超过90%。固然,前提是应用的内存使用量大于2G才行。不然分配给2G的堆内存,则不会使用这么高。可能用到1.5G左右就释放了。效率

 

再来讲说垃圾回收机制。这里我将G1算法以外的统称为老算法。我们来比较一下:监控

在8G堆内存的docker上,同一个应用,同一业务,压测结果以下:

1. young gc次数,老算法20次,G1算法8次。

2. 堆内存使用最大值,老算法使用最大6.3G,G1算法使用最大7.6G。

能够看出,在8G堆内存的场景下,G1算法总体表现优异,更少的gc次数,更高效率的堆内存使用率。

可是在8G如下堆内存使用的场景中,G1算法则优点并不明显。因此强烈建议堆内存比较大的应用开启G1算法。

 

最后说下,遇到此短信提示须要检查的内容。

1. 检查yong gc耗时,平均耗时40ms之内正常,超过1s则须要排查问题。

2. 检查full gc次数,一分钟内数次或者数十次则显得频繁,须要排查。

3. 检查堆内存回收图形,若是内存使用率上去了,可是迟迟下不来,则意味着老年代没法回收,检查代码查明缘由,相似图形以下:

image

能够看到此图中,曲线上去后下不来,缘由是应用内部有个本地cache一直在运行且无过时机制致使,后来关闭掉此本地cache则回收正常。

4. 根据jvm使用率曲线的最高点来看当前堆内存大小是否符合设置,若是当前堆内存使用率顶点一直较高,则应用须要的内存比分配的堆内存要大一些,能够在内存资源足够的状况下尝试多分配一些堆内存。

相关文章
相关标签/搜索