arthas 排查内存溢出_大对象出没,内存不够了

作者简介:大厂一线 技术管理者。从crud开发到资深开发,再到研究员兼技术经理。《资深开发讲技术》 从一线实战中总结有故事,有背景的案例,希望带给大家一系列技术盛宴,欢迎关注,转发,讨论。

几年前我刚才从学校毕业,进入第一家公司去哪儿网,走出校门时只听过java,c语言到是挺熟的。感谢去哪儿网脱产培训3个月,培训的导师,都是一线的资深开发或者负责人,他们给我们讲了很多案例以及基础,当然也有很多作业。

虽然我在去哪儿网待的时间并不长,但是这些年过去了,我一直心存感激。

为什么我要提我上面的这段经历呢,因为有些东西,已经深入到我的骨髓中了。以至于我觉得很普通,很常见的东西,一些同学竟然不知道或者不重视。当然大家的经历不同,认知肯定会有差距。

今天我就讲下,查询数据大对象的问题。

背景

前段时间业务方反馈,我们负责的推荐服务数据不准确。我在家里远程和公司的一位同事紧急开始排查。需要说明一下,此业务刚刚移交给我们团队,共涉及到三个项目。

出问题的服务线上部署4个容器,负责数据管理,每个容器配置有安全检查,如果服务不健康的话,隔一段时间就会重启服务。

我们紧急请教了之前负责的同事,他告诉我们第一个容器CPU太高了。

排查上半场

登陆到一个有问题的容器,下载了一个arthas,试图去分析一下cpu的原因,但是很遗憾严重卡死了,根本绑不上进程,我试图是执行jstack,也是无果。(我记得上一次出现这个现象的是redis服务,由于异常流量过高,dba也反馈过此现象)

幸运的是此时日志可以打开,虽然很慢看了下日志,惨不忍睹,各种报错,但是分析了几个错误,不能够解释cpu过高的原因。

fade0295d3fc928d7eb129ec7a74ba77.png

然后日志也看不到了,容器不健康被杀死了重启了。其他容器cpu并不高!!!很遗憾。我们只能下载日志去排查,可是日志量很大,windows根本打不开。

我和公司的开发商量如何分析日志的时候,发现其他容器也出现unhealth,而且基本上发现不到10分钟,一个容器就会挂掉,然后重启。

发现这样的规律后就好说了,我们在一台容器上,部署好了arthas等着问题复现,看下到底是那个线程出现了问题。

可以发现cpu占比最高的一直都是arthas,最高的线程占比大约5%到20%之间波动,解释不通啊。

排查中场

容器还在不断的kill然后重启,一顿折腾1个多小时过去了。期间我们紧急处理,数据已经恢复正常。但是问题还没有定位到。

突然我的同事告诉我,可能是fullgc引起的,他反馈每次fullgc失败和服务重启时间也差不多这个时候附近,之前我们的精力很停留在为啥cpu占用过高上

我们看了下gc日志,发现频繁fullgc,gc后依然申请不到内存。

我同事dump下了内存,使用MAT查看了,MAT直接显示内存泄漏。一个对象中有几十万个对象。而且定位到的方法和cpu过高的方法吻合。

我们基本确定了问题后,内存扩大了一倍,观察了下服务稳定,此时已经凌晨了。

排查后半场

第二天早上,主要看下了gc日志,发现频繁的从survivor中,固定的申请450M的内存。我们看了下出问题的那块代码,频繁的类似从mongo库中直接findAll,每次取出来几十万的对象,放在list中,然后循环处理。

这个task其实已经上线很长时间了,我理解不应该之前没有问题,最近才出现。我把我的疑虑告诉了,我们的开发。

我们先上线,优化了此处的问题,发现服务不会挂了,但是依旧还是比较吃内存。陆陆续续又发现了好几处,查询大对象的问题,解决后此服务暂时稳定。

总结

查询数据库的时候,特别是findAll,一定要问下自己,数据量是不是很大。

超过1千条,我建议走分页查询。

这是我在上家公司,培训的时候学到的。现在分享给你们。希望大家少故障,生活更美好

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值