Gets the number of strong references to a memoized object or class.
getrefcount is a low-level utility useful for debugging and understanding memory management within dbzero. It tells you how many other objects, tags, or class instantiations are "pointing" to a given object or class, keeping it alive in memory.
getrefcount(obj)
Checks how many strong references point to a specific memoized object or a memoized class.
Parameters
- obj (
dbzero.MemoBase|type): Thedbzeroobject instance or the class type you want to inspect.
Returns
int: An integer representing the total number of strong references. A count of0for an object means it's eligible for garbage collection during the nextcommit.
How It Works 🧐
The reference count for an object or class is incremented by:
- Object-to-Object References: When one memo object holds a reference to another as an attribute.
- Tagging: When you add a tag to an object using
dbzero.tags(obj).add(...). Each tag acts as a reference. - Class Instantiation: When you query the refcount of a class, the count increases for every instance of that class created.
Conversely, the count decreases when a reference is removed (e.g., setting an attribute to None) or a tag is removed.
Strong vs. Weak References
References created with dbzero.weak_proxy(obj) are weak and are not counted by getrefcount. This is a key feature for creating links between objects (especially across different database prefixes) without creating a hard dependency that would prevent the referenced object from being garbage-collected.
Examples
Basic Object Reference Counting
You can see how creating a reference from one object to another increases the reference count.
# Assume MemoTestClass is a registered dbzero model
# Initially, object_B has no references pointing to it
object_B = MemoTestClass(value=200)
print(db0.getrefcount(object_B)) # Output: 0
# object_A now holds a strong reference to object_B
object_A = MemoTestClass(value=object_B)
print(db0.getrefcount(object_B)) # Output: 1
# Removing the reference decreases the count
object_A.value = None
db0.commit() # A commit might be needed to process the change
print(db0.getrefcount(object_B)) # Output: 0Class Instance Counting
When used on a class, getrefcount returns the number of instances of that class.
# Initially, let's see how many instances of MemoTestClass exist
# (This could be non-zero if other tests created some)
initial_count = db0.getrefcount(MemoTestClass)
print(f"Initial count: {initial_count}")
# Each new instance increases the class's reference count
obj1 = MemoTestClass(value=1)
obj2 = MemoTestClass(value=2)
print(db0.getrefcount(MemoTestClass)) # Output: Initial count + 2Effect of Tags on Reference Count
Applying tags to an object also increases its reference count.
my_object = MemoTestClass(value=300)
print(db0.getrefcount(my_object)) # Output: 0
# Add a tag
db0.tags(my_object).add("important")
db0.commit() # Commit to apply the tag change
print(db0.getrefcount(my_object)) # Output: 1
# Add another tag
db0.tags(my_object).add("archive")
db0.commit()
print(db0.getrefcount(my_object)) # Output: 2
# Remove a tag
db0.tags(my_object).remove("important")
db0.commit()
print(db0.getrefcount(my_object)) # Output: 1Ignoring Weak References
Using dbzero.weak_proxy creates a reference that does not affect the reference count.
# obj_1 has no references
obj_1 = MemoTestPxClass(123)
print(f"Refcount for obj_1: {db0.getrefcount(obj_1)}") # Output: 0
# Create obj_2 with a WEAK reference to obj_1
obj_2 = MemoTestPxClass(db0.weak_proxy(obj_1))
# The refcount of obj_1 remains unchanged because the proxy is weak
print(f"Refcount for obj_1 after weak ref: {db0.getrefcount(obj_1)}") # Output: 0