微服务常见内存泄漏实战分析

但是也不能设太小,因为在一个热点服务的工程中,mysql连接的复用是非常重要的,可以降低连接的创建成本,这个需要根据对应服务工程的mysql调用频率进行调整。最近发现线上环境偶尔会出现Pod重启的情况,虽然重启大法(K8S会自动维护Pod数,Pod出了问题会自动重启,感兴趣的话可以去了解K8S的机制)很有效,但是终归不是根本的解决办法,我们需要了解为什么会重启,然后解决它,不单单是技术人的觉悟,更重要的还是money(狗头微笑),万一哪天重要的服务跪了影响到用户,非得被老板扒层皮。
摘要由CSDN通过智能技术生成

一、背景

最近发现线上环境偶尔会出现Pod重启的情况,虽然重启大法(K8S会自动维护Pod数,Pod出了问题会自动重启,感兴趣的话可以去了解K8S的机制)很有效,但是终归不是根本的解决办法,我们需要了解为什么会重启,然后解决它,不单单是技术人的觉悟,更重要的还是money(狗头微笑),万一哪天重要的服务跪了影响到用户,非得被老板扒层皮。

  在这个背景下,我们需要针对Pod进行监控,然而,事情并没有那么简单。在成功上线后,线上频繁告警。这个刚松了口气的我突然紧张了起来,看了一眼钉钉告警消息,虽然不是Pod重启,但是却发现有好几个服务出现了堆内存占用率超过90%的情况,这下就很酸爽了……

  在这里,把一些常见的内存泄漏情况分析给大家,欢迎指教。

二、首先弄清楚内存泄漏和内存溢出

简单地说,内存泄漏(Memory leak)就是在内存中有很多对象没有被回收,一直占着内存;而内存溢出就是我们常说的OOM了。

内存泄漏最终可能会导致内存溢出,因此我们需要针对上面说的内存占用率超过90%的服务进行分析,找到问题才能解决问题,防止OOM。

三、怎么排查呢

首先当然是看配置的堆内存大小了,这些服务有的配了512M,有的配置了1024M,虽然可以直接修改Pod分配的内存大小以及java应用的启动参数来实现内存扩容,但是难保有一天继续出现内存泄漏或者内存溢出而重启的问题。

因此,我们第二步就是老实本分地把Dump文件拿下来分析一下。

四、工具

(1)首先准备好工具,这里我本着免费的原则,找了俩个,一个是jdk自带的jvisualvm.exe,还有就是MAT了。

(2)拿到dump文件后开始用工具分析,这里我比较推荐MAT,个人使用起来觉得jvisualvm不如MAT好用,MAT能快速给你定位到大对象,还有一些其他的功能,可以俩个一起用,先jvisualvm(JDK自带,不用额外下载),没有结果就用MAT。

五、真正的分析从这里开始

在下面,会列举4种遇到的导致内存泄漏的场景,通过图+部分源码的方式展示,另外2种很容易找到问题,简单略过。 PS:部分参考链接需翻墙。

(一)mongodb

正确来讲是mongodb驱动。 首先打开MAT,将hprof文件载入,可以看到Biggest Objects的饼图,我们直接看最大的那个:

选中最大的那个,右键选择List objects。打开后可以看到:

打开后如此图,我们点击Retained Heap进行降序,然后逐步展开这个对象树。

这里解释一下Shallow Heap和Retained Heap的区别,Shallow Heap是浅层堆,主要是对象本身,也就是对象头+成员变量(不包含值);而Retained Heap是保留堆,指的是一个对象被释放后,能释放的对象的所有引用的堆大小。因此,Retained Heap能更实际地反映堆占用大小,也是我们重点关注的地方。

我们可以直接看到这个类是mongodb的,于是到idea中搜一下这个类,发现这个类是mongodb的驱动包内的,如下:

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值