Memory Management And Garbage Collection In Python
By: Seyma Tas
Tags: Memory Management, Python, Data Science, Reference Counting, Computer Science

Memory Management And Garbage Collection In Python

Reference Counting and Generational Garbage Collection

You are at the right place if you have these questions while learning Python:

How is memory managed in Python?

What is garbage collection?

Which algorithms are used for memory management?

What is a cyclical reference?

How are Python objects stored in memory?

Let’s see if I can answer these questions and some more in this article:

I am starting with the fundamentals.

Python Is a Dynamically Typed Language.

We don’t declare the type of a variable when we assign a value to the variable in Python. It states the kind of variable in the runtime of the program. Other languages like C, C++, Java, etc.., there is a strict declaration of variables before assigning values to them.

As you can see below, we just assign a variable to an object and Python detects the type of the object.

Python detects the type of an object dynamically. Image by author made with Canva

How are Python objects stored in memory?

In C, C++, and Java we have variables and objects. Python has names, not variables. A Python object is stored in memory with names and references. A name is just a label for an object, so one object can have many names. A reference is a name(pointer) that refers to an object.

Every Python object has 3 things.

Python objects have three things: Type, value, and reference count. When we assign a name to a variable, its type is automatically detected by Python as we mentioned above. Value is declared while defining the object. Reference count is the number of names pointing that object.

Every Python object has three things. Image by author made with Canva

Garbage Collection:

Garbage collection is to release memory when the object is no longer in use. This system destroys the unused object and reuses its memory slot for new objects. You can imagine this as a recycling system in computers.

Python has an automated garbage collection. It has an algorithm to deallocate objects which are no longer needed. Python has two ways to delete the unused objects from the memory.

1. Reference counting:

The references are always counted and stored in memory.

In the example below, we assign c to 50. Even if we assign a new variable, the object is the same, the reference count increases by 1! Because every object has its own ID, we print the IDs of objects to see if they are the same or different.

Image by author made with Canva

When we change the value of a like in below, we create a new object. Now, a points to 60, b and c point to 50.

When we change a to None, we create a none object. Now the previous integer object has no reference, it is deleted by the garbage collection.

We assign b to a boolean object. The previous integer object is not deleted because it still has a reference by c.

Image by author made with Canva

Now we delete c. We decrease the reference count to c by one.

Image by author made with Canva

As you can see above, del() statement doesn’t delete objects, it removes the name (and reference) to the object. When the reference count is zero, the object is deleted from the system by the garbage collection.

Goods and bads of reference counting:

There are advantages and disadvantages of garbage collection by reference counting. For example, it is easy to implement. Programmers don’t have to worry about deleting objects when they are no longer used. However, this memory management is bad for memory itself! The algorithm always counts the reference numbers to the objects and stores the reference counts in the memory to keep the memory clean and make sure the programs run effectively.

Everything looks ok until now, but …

There is a problem!

The most important issue in reference counting garbage collection is that it doesn’t work in cyclical references.

What is a cyclical reference or reference cycle?

It is a situation in which an object refers to itself. The simplest cyclical reference is appending a list to itself.

The simplest cyclical reference. Image by author made with Canva

Reference counting alone can not destroy objects with cyclic references. If the reference count is not zero, the object cannot be deleted.

The solution to this problem is the second garbage collection method.

2. Generational Garbage Collection:

Generational garbage collection is a type of trace-based garbage collection. It can break cyclic references and delete the unused objects even if they are referred by themselves.

How does generational Garbage Collection work?

Python keeps track of every object in memory. 3 lists are created when a program is run. Generation 0, 1, and 2 lists.

Newly created objects are put in the Generation 0 list. A list is created for objects to discard. Reference cycles are detected. If an object has no outside references it is discarded. The objects who survived after this process are put in the Generation 1 list. The same steps are applied to the Generation 1 list. Survivals from the Generation 1 list are put in the Generation 2 list. The objects in the Generation 2 list stay there until the end of the program execution.

Generational garbage collection. Image by author made with Canva

Conclusion:

Python is a high-level language and we don’t have to do the memory management manually. Python garbage collection algorithm is very useful to open up space in the memory. Garbage collection is implemented in Python in two ways: reference counting and generational. When the reference count of an object reaches 0, reference counting garbage collection algorithm cleans up the object immediately. If you have a cycle, reference count doesn’t reach zero, you wait for the generational garbage collection algorithm to run and clean the object. While a programmer doesn’t have to think about garbage collection in Python, it can be useful to understand what is happening under the hood.

Hope I could answer the questions in the beginning of the article. For the questions you cannot find answers to:

Further reading:

Mutable and immutable objects in Python.

Here is an unpopular but great article in Medium

2. How to understand variables in Python.

Here is an interesting article about tuples.

3. Local and global namespaces.

Here is a detailed explanation from realpython.com

4. Tracing garbage collection.

Here is the Wikipedia link to “trace-based algorithms”.

5. Stack and heap memory.

Here is an explanation to “how variables are stored” from geekforgeeks.

Any suggestions to seymatas@gmail.com will be very appreciated!