Tushar Seth
Tushar Seth

Reputation: 613

why am I able to access element even after garbage collection in python?

I guess I am missing something here, but when I am doing forcefully garbage collection using gc.collect(), I shouldn't be able to access id(10) since that is not being referenced by any of the variable and even if i assume that id(10) call is creating the variable, is it creating at the same location? that is wierd

import gc
import time

x = 10
y = x
print('10 id is: ', id(10))
print('x id is: ',id(x))
print('y id is: ',id(y))

x = x+1
y = 11
print('x id is: ',id(x))
print('y id is: ',id(y))
# above is justified
gc.collect(generation=2)
time.sleep(2)
print(id(10))
# but how come is above statement giving the value of id(10) as earlier?

When I run this snippet:

line1: 10 id is:  140709303001776
line2: x id is:  140709303001776
line3: y id is:  140709303001776
line4: x id is:  140709303001808
line5: y id is:  140709303001808
line6: 140709303001776

so how come in line6, i am able to get the id(10) as the same I had allocated earlier, since now x and y are pointing to different memories and I have garbage collected before printing line6

Please help me in this snippet as to how is the memory allocation working as this got me confused.

Upvotes: 1

Views: 79

Answers (2)

user20875810
user20875810

Reputation: 1

For efficiency Python has small integers (from -5 to 256 inclusive) in a cache, so they are never allocated again when needed. You can read about it in this question and its accepted answer: What's with the integer cache maintained by the interpreter?

One good way to check if the value is cached is doing a is (a - 1 + 1), it will be True only if value of a is cached.

  • by which I mean CPython from python.org, other implementations might do things differently, especially something gc related which doesn't affect usual Python code semantics.

Upvotes: 0

bb1950328
bb1950328

Reputation: 1599

Maybe the python interpreter itself or an imported module also has a variable with the value 10. So there some more references to to the value 10. I extended your snippet to prove that:

import gc
import time
import sys

x = 10
y = x
print('10 id is: ', id(10))
print('x id is: ',id(x))
print('y id is: ',id(y))
print("References to 10:", sys.getrefcount(10))

x = x+1
y = 11
print('x id is: ',id(x))
print('y id is: ',id(y))

gc.collect(generation=2)
time.sleep(2)
print("References to 10:", sys.getrefcount(10))
print(id(10))

Output on my machine:

10 id is:  140076230383168
x id is:  140076230383168
y id is:  140076230383168
References to 10: 20
x id is:  140076230383200
y id is:  140076230383200
References to 10: 18
140076230383168

Upvotes: 1

Related Questions