Issue 1030249: socket is not garbage-collected under specific circumstances (original) (raw)

Logged In: YES user_id=21627

This is not a bug in Python. You are creating a cyclic structure (where Session._parser refers to an ExpatParser, the ExpatParser refers to the bound method Session.starttag, and that refers back to the Session object).

Python makes no guarantee that the memory for a cyclic structure is released at a specific point; instead, different Python versions may work differently in this matter. The current implementation invokes garbage collection "from time to time", where this more precisely means "after gc.get_threshold()[0] more objects have been allocated than deallocated".

Applications should not rely on garbage collection for closing sockets. Instead, they should use an destroy mechanism. In the specific example, just add a destroy method to Session that reads

def destroy(self): self.socket.close() self.parser.reset() del self._parser

The latter two aren't really necessary, since GC will reclaim the memory of the objects eventually, but explicitly breaking the cycle means that the memory will be reclaimed even before cyclic GC is invoked.