Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

garbage collection doesn't remove unreachable object after being turned off for a while

I have the following hypothetical Python program that uses some of the garbage collector functions (documentation):

import gc

# Should turn automatic garbage collection off
gc.disable()

# Create the string
a = "Awesome string number 1"

# Make the previously assigned string unreachable
# (as an immutable object, will be replaced, not edited)
a = "Let's replace it by another string"

# According to the docs, collect the garbage and returns the
# number of objects collected
print gc.collect()

The program prints 0, which seems weird to me because:

  • Upon first assignment, the str object is created and is referenced by a.
  • Upon the second assignment, the second str object is created and a and now referenced by a.
  • However, the first str object was never deleted because we have turned off automatic garbage collection, thus it still exists in the memory.
  • Since it does exist in the memory, but is unreachable, that seems like exactly the kind of object the garbage collection should remove.

I would greatly appreciate an explanation of why it's not collected.

P.S. I do know that Python treats some objects (including integers from -3 to 100, as far as I remember) as singletons, but there is no way these particular strings are such objects.

P.P.S I am running it as a whole program, not in the shell

like image 658
Dmitry Torba Avatar asked Jan 23 '18 00:01

Dmitry Torba


1 Answers

The gc module in Python is only responsible for collecting circular structures. Simple objects like strings are reclaimed immediately when their reference count becomes 0. gc doesn't report on simple objects, and disabling it doesn't prevent strings from being reclaimed.

Extra advanced detail: even if the gc module were responsible for all object reclamation, the first string still wouldn't be collected at the gc.collect() call, because there's still a live reference to that string: the reference in the co_consts tuple of the script's code object.

like image 168
Ned Batchelder Avatar answered Nov 15 '22 18:11

Ned Batchelder