记录一次线上服务器内存泄漏

背景

最近上线了一个网页解析的相关业务(懂得都懂),由于调用频率不高故不用考虑并发的问题.于是差不多写了一个下午本地测着没什么问题就上线跑了。跑了大概四五天的样子,该节点服务器宕机,good,头一回碰到这种事情,我就去找运维要root权限看日志,top命令显示res撑满了,可不就是内存溢出呗,先给调大一个g重启后跑着,接下来就是一顿分析…

一顿分析猛如虎

重启该服务后,跑了两三天后用top 查看cpu使用率
top
其中这个9178进程就是这次的排查对象,刚重启那会儿我记得是900m左右来着,把内存调到2个g之后仍在增长说明不是内存不够引起的,用 top -Hp pid (pid是进程号或者线程号)查看该进程下的线程使用情况top-Hp
看出什么了吗,并没有…
没有得逞,继续找呗,排查gc问题正常流程,走!
没发现有哪个线程特别突出(cpu占用过高啦,内存飙升啦这些),之后用jstack 9178 | -A 30 5dbd 随便找了第一个进程23997查看该线程的堆栈情况, 9178是该线程所属进程号, 5dbd是23997的十六进制,用命令printf %x pid 即可,温馨提示,先获取root权限噢
jstack

emm…依然看不出什么毛病,不过在同样分析了该进程下的几个线程后发现都是此线程htmlunit在占用,看下该进程类的创建情况吧
jmap-histo
除了java自带的,大多是htmlunit的类,似乎有了方向,光看这还不通透,把堆得使用情况导到出来,所用命令
jmap -dump:format=b,file=d:\workfiles\heaplog\20210913init\heap.hprof 9178
接着用mat打开该文件看看,嚯啊哦,一看吓一跳!
mat_1
网上搜了一下,HtmlPage在使用不当时确实会存在内存泄漏的问题,于是代码做了一些优化
majorization
下面是本地jvm代码优化前后的对比图,用jconsole分析的
优化前,在10:10左右调用了一次触发gc,等了有20多分钟看看运行情况,观察了一会儿已经不正常了…,比接口调用前高出好多,在10:35之后再次调用接口触发gc,之后又调用了几次,情况如下
jonsole_pre
下面是优化前的堆使用情况,可以观察htmlunit线程占用较多
mat_pre
mat_pre_detail
下面是优化后堆的使用情况,12:00调用接口触发gc,故意在第一次调用和第二次调用之间隔较长看看如何,于是取吃了个饭眯了一会儿,看情况比优化前好多了,到13:30调用第二次接口并触发gc,方便查看这次截了个大图
jconsole_later_big
这是mat分析优化后的堆使用情况分布图,htmlunit消失了,仿佛一颗陈年鼻屎被抠掉了,成就感十足!
mat_later
上线后该服务稳定运行,占用内存不再持续上升,下面是该节点服务重启后运行两天的top状况,稳定在1g.
top-run2day
下图是该服务跑了9天之后的top状况,相当稳定了~
top-run9day
至此,一次内存泄漏的事故算是告一段落.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值