Understanding Python's Internal Memory Management: A Practical Guide โœจ

Avni SinghAvni Singh
4 min read

This article aims to demystify how Python handles memory allocation, reference counting, mutable and immutable types, and the distinction between value and reference in variables. We'll also visualize code behaviour in memory and clarify key concepts vital for both beginners and for interview preparation.


๐Ÿง  Python's Memory Management Magic

  • First things first - Python does a lot of internal optimization including memory allocation, freeing up memory, and handling mutable vs immutable objects in special ways.

  • Python doesn't keep empty references hanging around. It has an automatic garbage collector that takes care of this.

๐Ÿ’ก
Numbers and strings are treated differently than other types. Because these are immutable, Python often reuses the same memory location for identical values (a performance trick called interning).
  • When a reference gets freed, it's not deleted immediately. Python waits for some time because with numbers and strings, the same value might be created multiple times for optimization purposes.

Reference Counting: Python's Secret Tracker

Since there can be multiple references for a single value, Python keeps track of them all. You can actually check a value's reference count, but here's a quirky thing - you can't always get the "proper" value printed because the compiler does multiple optimizations that affect this.

What's really mind-blowing is that even when we haven't explicitly created values in our program, we can still get a reference count value. Python's working hard behind the scenes!

>>> import sys
>>> sys.getrefcount(24601)
3
>>> sys.getrefcount('pig')
3
>>> sys.getrefcount(1)
4294967295

๐Ÿท๏ธ How Python Handles Data Types

๐Ÿ’ก
Here's an important concept that often comes up in interviews: In Python, the data type belongs to the value in memory, not to the variable. Python doesn't assign any data type to the variable itself, but rather to the value that's stored in memory.

This makes sense because a variable can be a reference to any type of value that gets assigned to it. Remember this - it's crucial for understanding Python's behavior!


๐Ÿ–ผ๏ธ Visualizing Memory Operations

Let's look at some examples to see how Python handles things in memory:

Example 1: Simple Number Operations

>>> a = 5
>>> b = 2
>>> a
5
>>> b
2
>>> a = a + 2
>>> a
7

What happens:

  1. References to 5 and 2 are created

  2. In a = a + 2 , Python gets reference values before calculation

  3. Then performs the calculation


Example 2: List Mutability

>>> l1 = [1,2,3]
>>> l2 = l1
>>> l1[0] = 44
[44, 2, 3]
>>> l2
[44, 2, 3]

Now both l1 and l2 show [44, 2, 3] because:

  • We assigned l2 as a reference to l1

  • Lists are mutable, so changes to l1 affect l2


Example 3: The Tricky Part

>>> l1 = [1,2,3]
>>> l2 = l1
>>> l2 = [1,2,3]
>>> l1[0] = 55
>>> l1
[55, 2, 3]
>>> l2
[1, 2, 3]

Now here's where people get confused. After l2 = l1, we assign the same values to l2 again. You might think they'd have the same reference - but nope! Changing l1 doesn't affect l2 now because they're different objects.


Example 4: The Slicing Surprise

>>> l1 = [1,2,3]
>>> l2 = l1[:]
>>> l1[0] = 55
>>> l1
[55, 2, 3]
>>> l2
[1, 2, 3]

Here, l2 doesn't change when we modify l1. Why? Because [:] creates a copy of the list - it's not referencing the original list anymore!


โš”๏ธ The "==" vs "is" Operator Showdown

OperatorChecksExample
==Value equality[1,2] == [1,2] โ†’ True
isMemory identity[1,2] is [1,2] โ†’ False

This is a classic Python interview question:

  • == checks if the values in the objects are equal

  • is checks if they're the exact same object in memory (same reference)

For example:

>>> a = [1, 2, 3]
>>> b = [1, 2, 3]
>>> a == b  # True - same values
True
>>> a is b  # False - different objects in memory
False

Wrapping Up ๐ŸŽˆ

Python's memory management and optimization strategies are fascinating once you peek under the hood. Understanding these concepts helps you write more efficient code and debug tricky situations.

Remember:

  • Numbers and strings: special handling for optimization.

  • Variables: Always references to typed values in memory.

  • List assignment and slicing: watch out for reference vs copy!

  • \== vs is: Know the difference for comparisons.

I hope this deep dive helps you in your Python journey! What other Python internals would you like to understand better? Let me know in the comments! ๐Ÿš€

3
Subscribe to my newsletter

Read articles from Avni Singh directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Avni Singh
Avni Singh