客户端接受多个对话请求或者打开多个会议室之后会堆内存耗尽而退出,使用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 <-

博客讨论了Spark应用在处理多个对话请求或会议室时出现的内存泄漏问题。通过jconsole和jprofile分析,发现GroupChatRoom对象和MultiUserChat对象在关闭后仍存在,无法被垃圾回收。问题根源在于ChatTranscriptManager的lastMessage持久引用未正确清理,以及MultiUserChat的引用链导致的对象无法释放。解决方案包括改进filterChatRoom方法和在离开时解除MultiUserChat的引用。
最低0.47元/天 解锁文章
7635

被折叠的 条评论
为什么被折叠?



