Memory Management and Execution on Windows — Python (CPython)

Last updated: December 13, 2025
Author: Paul Namalomba
- SESKA Computational Engineer
- Software Developer
- PhD Candidate (Civil Engineering Spec. Computational and Applied Mechanics)

Contact: kabwenzenamalomba@gmail.com
Website: paulnamalomba.github.io

Language: Python Interpreter: CPython License: MIT

Overview

This guide explains how Python (CPython on Windows) handles key memory and execution concepts: value vs reference semantics, heap storage, copy semantics (deep vs shallow), and nullability. The content focuses on what actually happens under the hood on Windows using CPython, with short, runnable examples and Windows-specific notes.

Contents


Windows — Run (PowerShell / Command Prompt)

```powershell # PowerShell python main.py

# If multiple versions installed, use py launcher py -3 main.py ```


Overview

Python (CPython) provides high-level memory management with automatic memory allocation, reference counting, and a cyclic garbage collector. This guide explains how Python handles value vs reference semantics (always objects), memory allocation (heap-managed objects), copy semantics (shallow vs deep), and nullability (None). Examples demonstrate behaviour and best practices for Windows environments.


Contents


1) Data Structures — "Value" vs "Reference" in Python

Example:

# assignment binds names to objects
a = 10
b = a  # both names point to same int object
b = 20 # b now points to new int object; a unchanged

lst1 = [1,2,3]
lst2 = lst1
lst2.append(4)
print(lst1)  # [1,2,3,4]

Notes: - Understanding mutability is essential: immutable types are safe to share, mutable types require attention.


2) Storage — Heap, Object Layout, and CPython Internals

Reference counting & GC: - CPython primarily uses reference counting (immediate deallocation when refcount drops to zero). - It also has a cyclic garbage collector (gc module) to detect and collect reference cycles.

Windows specifics: - CPython uses the Windows heap API under-the-hood; performance tuning is limited compared to native languages.


3) Copy Semantics — Shallow vs Deep Copy

Example:

import copy
orig = [[1,2],[3,4]]
shallow = copy.copy(orig)
deep = copy.deepcopy(orig)
orig[0].append(9)
print(shallow) # shares nested lists -> shows change
print(deep)    # independent copy -> no change

Tips: - Prefer immutable objects for safety. - Use deepcopy cautiously — expensive for large structures.


4) Nullability — None and Safe Usage

Example:

x = None
if x is None:
    print('no value')

Pitfalls: - Do not use == None; use is None for identity. - Be careful with mutable default arguments in function signatures; use None sentinel.

def append_to(element, to=None):
    if to is None:
        to = []
    to.append(element)
    return to

Examples — Runnable Snippets

main.py:

import copy

# Data structure behavior
x = 10
y = x
print(x, y)

lst = [1,2]
alias = lst
alias.append(3)
print('alias modifies original:', lst)

# Shallow vs deep copy
orig = [[1],[2]]
shallow = copy.copy(orig)
deep = copy.deepcopy(orig)
orig[0].append(99)
print('shallow:', shallow)
print('deep   :', deep)

# None usage
maybe = None
print('maybe is None ->', maybe is None)

Run with python main.py or py -3 main.py on Windows.


Windows / CPython Specific Notes


References

End of Python guide.