Reference Counting in Python (Techniques & Examples)

Reference counting is the process of counting how many times certain memory address is referenced.

Introduction

Every variable in Python is a reference to an object and not the actual value. This reference is also known as Pointer to an object.

For example: if we create variable a by assigning some value then its value is stored in some memory location as an object of type corresponding to value i.e. if assigned value is 10 then it will be of type int, and variable a will reference or point to that object in memory.

Reference or memory location can be found using built-in function id(). But remember! a is just a reference not a value.


>>> a=20
>>> id(a)
1947728096

1947728096 is memory address or reference for variable a. Here reference count for location 1947728096 is 1 since it is referenced by only variable a.

When we assign value of variable a to another variable b then variable b is not created in memory but it will reference variable a, this can be illustrated as:


>>> a=20
>>> id(a)
1947728096
>>> b=a
>>> id(b)
1947728096

Here both variables a and b are referencing the same memory address 1947728096. Here reference count for location 1947728096 is 2 since it is referenced by variable a and b.

Key Points

Python memory manager keeps track of number of references to those objects.

When reference count becomes zero to any object, Python memory manager destroys that object and reclaims memory.

Concept of reference counting is very important for understanding Garbage Collection in Python.

Reference Counting Techniques

There are two simple approach or techniques for reference counting.

  1. First approach is using module sys which has method called getrefcount() and accepts variable as an argument. But! This approach creates an extra reference while calling it! So you will get count one more than actual reference count. Keep that in mind!
  2. Second approach is using module ctypes which has sub-module called c_long and this sub-module has method from_address() which accepts address as an argument. And calling method value on from_address gives you reference count. This approach does not create extra reference unlike getrefcount() in sys module.

Example Using sys Module

Following example uses sys module for reference counting:


>>> my_var = 'Python rocks'
>>> another_var = my_var
>>> yet_another_var = another_var
>>> sys.getrefcount(my_var)
4

Example Using ctypes Module

Following example uses ctypes module for reference counting:


>>> my_var = 'Python rocks'
>>> another_var = my_var
>>> yet_another_var = another_var
>>> ctypes.c_long.from_address(id(my_var)).value
3