1、 监控机上经常有agent无缘无故的僵死掉了,通过web发送请求,报出collectionagent timeout的提示信息,环境平台上显示agent状态为异常。
2、处理过程
1)登陆到机器,进入查看监控数据,有大量的dubbo监控信息。查看agent进程内存使用情况,DubboInvoker对象已经有10000多个了,表明这个对象没有销毁。
2)查看源码,主要是调用dubbo二方库,找到了产生DubboInvoker对象的方法,但在finally中调用了reference的destory()方法,本地断点测试,发现这个destory并没有销毁对象。想着在finally中将reference赋值为null,在jvm做GC时将其回收掉,但是,发现并没有回收掉,因为二方库中的引用和反射仍然存在,不能被回收。
3)与dubbo接口人沟通,得到的结论是这个方法确实销毁不了对象,只有我一个人用这个方法,这个方法处理太过复杂,现在已经不进一步处理了,不过有个思路还不错,就是把所有要监控的dubbo服务全部初始化好,要调用时就直接取就行,对象不用销毁。
4)根据这个建议,我们每台机器上的dubbo监控基本上都是固定的,只是每隔几十妙循环发送,也就是说对象的重用性非常强。对代码做了如下改变:用了一个map将reference对象存储起来,后来每次从map中取就行,不用每次new一个对象了。
总结:这是一个二方库的bug引出的内存泄露,被迫用了map存储对象,其实反过来想想,我们后续的代码中类似这样的大对象和重复利用率高的对象能否考虑也存储起来呢,而不用频繁的创建和销毁,减少这方面的开销!