I am running a memory profiler on a codebase written by me using Smack 2.2.1. And I have noticed that even after calling close() on XMPPConnection, the PacketListeners/PacketCollector are not getting dereferenced and hence there instances are failing to be collected by GarbageCollector. Leading to a possile Memory Leak scenario.
I looked at the Smack code and observed that when the Connection is closed, shutdown is called on the packetWriter and packetReader, following is the snippet from the close method of XMPPConnection
public void close() {
// Set presence to offline.
packetWriter.sendPacket(new Presence(Presence.Type.UNAVAILABLE));
packetReader.shutdown();
packetWriter.shutdown();
…
The shutdown method of PacketReader shuts down the connection listeners as follows
public void shutdown() {
// Notify connection listeners of the connection closing if done hasn’'t already been set.
if (!done) {
ArrayList listenersCopy;
synchronized (connectionListeners) {
// Make a copy since it’'s possible that a listener will be removed from the list
listenersCopy = new ArrayList(connectionListeners);
for (Iterator i=listenersCopy.iterator(); i.hasNext(); ) {
ConnectionListener listener = (ConnectionListener)i.next();
listener.connectionClosed();
…
This would remove all the connectionListeners, but the PacketListeners(wrapped in ListenerWrapper, as a part of the List listeners) will still remain.
I am not storing references of PacketListeners in the code, I just add a PacktListener to the XMPPConnection and only keep the reference of the connection. Finally, I call close on the connection and dereference the connection object instance. I believe that all the PacketListener/ListenerWrapper/ etc. shd get dereferenced once the connection is closed and dereferenced. Am I missing something?
Thanks
Videh