Concepts / Memory Management and Garbage Collection

Memory Management and Garbage Collection

Objects have a complete lifecycle: creation (via __init__), active use, and destruction (via __del__). Python calls these special methods automatically.

  • Programming

The Object Lifecycle

A Python object passes through three broad stages: creation, active use, and destruction. During creation, Python allocates memory and calls __init__. During active use, your code can call the object's methods and access its attributes. During destruction, Python calls __del__ if the class defines it, giving the object a final opportunity to perform cleanup before it disappears from memory.

Python callsafter setupno longer neededif definedObject creationMemory allocated__init__Set up values and resourcesActive useMethods and attributesavailableObject destructionObject no longer needed__del__Final cleanup opportunity
What happens to an object, and which special method is called, at each stage from creation through destruction?

Automatic Lifecycle Methods

__init__ and __del__ are special methods that Python calls automatically at important lifecycle moments. __init__ runs when an object is created. It can establish initial attribute values and prepare resources the object needs. __del__ runs just before an object is destroyed, if the class defines that method. It can release resources or perform other necessary final cleanup.

Lifecycle methodWhen Python calls itPurpose
__init__When an object is createdInitialize attributes and prepare resources
__del__Just before an object is destroyedPerform final cleanup or release resources

A destructor is the __del__ method of a class. It is invoked when an object is about to be destroyed. You cannot use it to prevent destruction; you use it to perform cleanup during that final moment.

Reassignment and Destruction

Reassignment can remove a variable's connection to its old object. Imagine a variable named animal referring to a PartyAnimal object. If the variable is reassigned to 42, animal no longer refers to that PartyAnimal object. When Python decides that the old object is no longer needed, it destroys the object and calls its __del__ method if one exists.

refers toold object no longer neededbefore destructionanimalrefers to PartyAnimal42new value of animalPartyAnimalactive objectPartyAnimaleligible for destruction__del__final cleanup if defined
How does reassigning a variable remove its reference to the old object and cause that object to become eligible for destruction?

Tracing a Reassigned Object

Trace what happens when a variable first refers to an object and is later assigned a different value.

Create: Python creates the object, allocates memory, and calls __init__ so the object can establish its initial state.

Use: The variable refers to the object, so code can use the object's methods and attributes.

Reassign: The variable is assigned a different value. It no longer refers to the original object.

Destroy: When Python decides the original object is no longer needed, it destroys that object and calls __del__ if the method was defined.

Reassignment can trigger the original object's destruction because the variable that held it has been assigned something else.

The Final Cleanup Sequence

Python decidescheck methodyesnoafter cleanupObject no longerneededPython destroysobject__del__ definedFinal cleanuprelease resourcesObject vanishes
What happens next when an object is destroyed, and when does __del__ perform its cleanup task?

The key sequence is not that __del__ keeps an object alive. Instead, Python first determines that the object is about to be destroyed. If the class defines __del__, Python calls that method just before the object vanishes. The method provides a final chance to release resources or perform necessary cleanup, but it cannot stop the destruction.

Define __del__ only when an object manages an external resource that needs final cleanup. Ordinary Python objects usually do not need a destructor because Python's garbage collector automatically reclaims memory when objects are no longer in use.

Termination and External Resources

program reaches endbefore exitif method existsafter final cleanupProgram runningobjects remain availableProgram terminationRemaining objectsdestroyed before exit__del__cleanup if definedProgram exits
How does object cleanup proceed when the program reaches termination instead of a variable being reassigned?

Program termination changes the trigger, not the general purpose of __del__. Instead of a variable being reassigned, the program reaches its end. The remaining objects are destroyed before the program exits, and a defined __del__ method provides the final cleanup opportunity for each object.

Destructors are most useful when an object manages resources outside ordinary Python memory. The source examples include open file handles, database connections, and network sockets. A destructor can close or release such a resource during the object's final cleanup. Without cleanup, those resources might remain open longer than necessary, potentially exhausting system limits or causing data loss.

Mistakes in Lifecycle Tracing

  • Assuming __del__ runs when the object is created

    The two methods serve opposite lifecycle moments.

    Fix: Associate __init__ with creation and setup, and __del__ with final cleanup before destruction.

  • Thinking reassignment destroys the new value

    Reassignment removes the variable's reference to its previous object.

    Fix: Trace which object the variable referred to before reassignment, then determine whether that old object is no longer needed.

  • Treating __del__ as a way to prevent destruction

    The destructor does not cancel the destruction process.

    Fix: Use __del__ only for final cleanup tasks.

  • Adding __del__ to every class

    Python's garbage collector automatically reclaims memory for objects that are no longer in use.

    Fix: Consider __del__ when the object manages an external resource such as a file handle, database connection, or network socket.

Lifecycle Practice

MEDIUM

Trace this scenario in four stages: a class creates an object and initializes it; the object is used; the variable holding it is assigned a different value; the program later reaches termination. For each stage, identify whether __init__, normal object use, or __del__ is involved. Then explain why the object does not need a destructor if it manages only ordinary Python data.

Hints
  • Start with the creation stage and identify the special method called there.
  • At reassignment, focus on the old object rather than the new value.
  • Use the external-resource rule to decide whether a destructor is useful.

Key Takeaways

  1. An object moves through creation, active use, and destruction.
  2. __init__ is called automatically during creation; __del__ is called before destruction when it is defined.
  3. Reassignment, a variable leaving scope, and program termination can make an object no longer needed.
  4. A destructor cannot prevent destruction; it provides a final opportunity for cleanup.
  5. Most objects need no destructor because Python automatically manages ordinary memory. Destructors are mainly useful for external resources such as files, database connections, and network sockets.

Key Takeaways

  • Python objects have a lifecycle consisting of creation, active use, and destruction.
  • __init__ prepares an object, while __del__ performs final cleanup before destruction.
  • Reassignment, scope changes, and program termination can trigger destruction when Python decides an object is no longer needed.
  • Most objects do not require __del__; it is primarily useful for releasing external resources.