0

The following code is run on Mac terminal on Python3:

import gc
import numpy as np
class D(object):
 def __init__(self):
 self.value = np.arange(3)
 def get(self):
 return self.value
d = D()
print(gc.get_referrers(d))
print(type(gc.get_referrers(d)))
print()
print(len(gc.get_referrers(d)))
print(len(gc.get_referrers(d.value)))
print()
l = []
l.append(d)
print(len(gc.get_referrers(d)))
print(len(gc.get_referrers(d.value)))
print()
x = d.value
print(len(gc.get_referrers(d)))
print(len(gc.get_referrers(d.value)))

The above code will return:

[{'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x10de6cef0>, '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>, '__file__': 'test3.py', '__cached__': None, 'gc': <module 'gc' (built-in)>, 'np': <module 'numpy' from '/Users/jkim/Codes/Codes/Notebooks/venv3/lib/python3.6/site-packages/numpy/__init__.py'>, 'D': <class '__main__.D'>, 'd': <__main__.D object at 0x10dec7fd0>}]
<class 'list'>
1
0
2
0
2
1

Could anyone explain to me:

  1. Why is reference count to d.value 0, and if the reference count to d.value is indeed 0, why is d.value not getting garbage collected by Python?

  2. What exactly is the list that the object d is being referred by?

Thank you!

asked Mar 17, 2020 at 22:22
2
  • Why are you subclassing object? Is this Python 2? If so, please tag it as such. Commented Mar 17, 2020 at 22:26
  • This is python3. I did it out of force of habit. Thank you for the edits Commented Mar 17, 2020 at 22:31

1 Answer 1

1
  1. The reference count is not 0. You cannot observe an object with a 0 reference count in CPython; you need a reference to an object to do anything with it, and that reference will count toward its reference count. What you're seeing is that there are no GC-tracked referrers for the object. If you want the actual reference count, use sys.getrefcount.
  2. There is no list with a reference to the object. You're taking the type of the list of referrers returned by gc.get_referrers. This list is not itself a referrer of the object.

d.value has no GC-tracked referrers for the following reason. First, d.value is a NumPy array with a dtype that cannot hold object references, so it cannot participate in a reference cycle. The NumPy implementation optimizes such arrays by making them GC-untracked.

Second, the only references to d.value are one reference in d.__dict__, and the temporary references created when you access d.value or pass it to gc.get_referrers. The temporary references live in the current stack frame's bytecode operand stack, or in C local variables, and those locations aren't visible to the GC. d.__dict__ has only ever held objects that cannot be GC-tracked (the array and the 'value' string), and the CPython dict implementation does not GC-track a dict until a key or value is inserted that is capable of being GC-tracked (or in some cases when a dict is created as a copy of a tracked dict).

answered Mar 17, 2020 at 23:51
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.