This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: socket is not garbage-collected under specific circumstances
Type: Stage:
Components: Extension Modules Versions: Python 2.3
process
Status: closed Resolution: not a bug
Dependencies: Superseder:
Assigned To: Nosy List: doko, loewis
Priority: normal Keywords:

Created on 2004-09-18 07:11 by doko, last changed 2022-04-11 14:56 by admin. This issue is now closed.

Files
File name Uploaded Description Edit
autogc.py doko, 2004-09-18 07:11 sample code
Messages (2)
msg22481 - (view) Author: Matthias Klose (doko) * (Python committer) Date: 2004-09-18 07:11
[forwarded from http://bugs.debian.org/271169]

seen with current 2.3 branch and 2.4a3.

bug submitter writes:

Hello.
I have found strange behaivoir: when my class uses
xml.parsers.expat
parser then the attributes, assigned to this class is not
garbage-collected.

I've attached a little script to show this.
The test is simple:
script listening to port 1024 and awaiting first
connection.
upon incoming connect it creates the class instance in
question and then
_destroys_all_ that it just created. Then sleeps for 5
secods.
If the bug is not activated (rem the 8th line) then the
connection is
closed immidiatedly after estabilishing. If activated -
only after
script exit.

So the test is simple:
start script in one console
run the "telnet 127.0.0.1 1024" in other console.
see that telnet waits 5 seconds instead of immediate
disconnect.
msg22482 - (view) Author: Martin v. Löwis (loewis) * (Python committer) Date: 2004-09-18 10:38
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.
History
Date User Action Args
2022-04-11 14:56:07adminsetgithub: 40924
2004-09-18 07:11:08dokocreate