MultiUserChat relies on finalize() being called in order to remove packet listeners and the association with RoomListenerMultiplexor. Unfortunately, if any of the listeners have references to MultiUserChat (which is common), MUC isn’t garbage collected, and memory leaks.
Firstly, using finalize is bad style because it isn’t guaranteed to be called in a timely manner by the GC. The following patch fixes the issue for us, by calling a cleanup function when leave() is invoked:
muc-finalize-fix.patch (620 Bytes)
I have filed this as SMACK-270. Hope devs will notice it.
This is a major leak, so I’m surprised it hasn’t received more attention.
The MultiUserChat is always strongly reachable until the connection dies, as one of the listeners added is an anonymous inner class of MultiUserChat, hence maintains an implicit reference to it. This causes huge scalability problems.
We have performed an automated soak test using Fastpath with 20 agents serving a realistic queue (users actively joining, chatting, leaving etc) and the JVM (with a 1.4GB heap) was brought to its knees in around 4 hours.
I have attached an updated patch to the JIRA in the hope that someone will be able to commit it into trunk ASAP.
I will ping Robin Collier about this. He is ready to release 3.2 Beta version, but maybe he will be able to include this fix too.
I will try to take a look tonight, but I can’t promise anything.
At this point I am trying to stick to more administrative tasks to get a release out. I don’t want to get sidetracked with bug fixes with the limited time I have available right now. My preference is to get a release out as is and fix a select set of issues after the beta but before the real release.
Once a process for the release is ironed out I can concentrate on bug fixes.