spark内存泄露的问题及解决

客户端接受多个对话请求或者打开多个会议室之后会堆内存耗尽而退出,使用jconsole检测可以发现它对堆内存的占用只升不降,使用jprofile可以发现关闭聊天室之后GroupChatRoom对象仍然存在,并且只增不减不能被垃圾回收最终耗尽堆内存,控制台抛出OuOfMemoryError。

jprofile可以查看存留对象的引用图(References Graph),从左边分析哪些对它的引用会导致它不能被垃圾回收,还可以计算到GC(垃圾回收)的路径,从这里可以查看路径中是否有全局对象。最后发现ChatTranscriptManager保存了对GroupChatRoom的持久引用,它没有恰当地从lastMessage中移除ChatRoom,并且由它注册的ChatRoomListener和被其他类调用的persistChatRoom(ChatRoom)在保存聊天记录时对ChatRoom的过滤不一致,前者只接受ChatRoomImpl实例,后者接受所有ChatRoom实例(包括GroupChatRoom实例),建议使用统一的filterChatRoom(ChatRoom)过滤合适的ChatRoom,并且在chatRoomClosed时从lastMessage中移除ChatRoom键。

同时还可以发现MultiUserChat也是只升不降,同样的分析可以发现存在这样的引用链MultiUserChat <- presenceListener <- packetMultiplexor <- roomListenerMultiplexor <- XMPPConnection,最后这个是全局对象只有客户端退出时才会过期,Ignite Realtime论坛上可以搜到一些关于memory leak的帖子然后发现有个fix patch在MultiUserChat的finalize方法里面从roomListenerMultiplexor解除了对packetMultiplexor的引用,显然这个方法是不可靠的,移除动作应该在leave的时候执行。

猜你喜欢

转载自blog.csdn.net/hwxia/article/details/6000846