nextRound
TechnologiesCoding ProblemsBookmarksLearning PathsLogin
nextRound
TechnologiesCoding ProblemsBookmarksLearning PathsLogin
nextRound

AI-powered interview preparation platform. Practice with curated questions, mock interviews, and personalized learning paths to crack your dream tech interview.

Quick Links

  • Technologies
  • Mock Interviews
  • Saved Questions
  • Pricing

Company

  • About Us
  • Contact Us

Legal

  • Privacy Policy
  • Terms of Use

© 2026 nextRound. All rights reserved.

Questions
10 of 12
1What is an Interpreted language?
2Is Python a compiled language or an interpreted language?
3What is the difference between `/` and `//` in Python?
4Why can `a = 256; b = 256; a is b` return `True`, but `a = 257; b = 257; a is b` return `False` in some Python implementations?
5What is the difference between a shallow copy and a deep copy? When would each cause bugs?
6What causes a reference cycle, and how does Python's garbage collector handle it?
7What is the difference between `is` and `==`?
8How does Python evaluate chained comparisons like `1 < x < 10`?
9What are Python's built-in data types, and how are they categorized (mutable vs. immutable)?
10How does Python manage memory for objects internally (reference counting and the object model)?
11Why does Python not require explicit variable declarations, and how does dynamic typing affect variable assignment internally?
12Why can floating-point arithmetic in Python produce results like `0.1 + 0.2 != 0.3`? How would you correctly compare floats?
PythonPython
Basics
Control Flow and Functions
Data Structures
Comprehensions & Functional Programming
Iterators, Generators & Decorators
Object-Oriented Programming
Exception Handling & Debugging
Concurrency & Parallelism
Performance & Optimization
Testing
Security
Modules, Packaging & Environment
Type Hinting & Modern Python
System Design & Architecture with Python
Best Practices & Design Patterns
Edge Cases & Tricky Interview Questions
10 / 12

How does Python manage memory for objects internally (reference counting and the object model)?

Difficulty: 8/10
Variables, Data Types & Memory Model, Reference Counting, CPython Object Model and Allocation

CPython object model, allocation and reference counting

In CPython everything is a heap-allocated PyObject. Each object starts with a header containing ob_refcnt (reference count) and ob_type (pointer to its type object); variable-sized objects such as lists, tuples and ints embed a PyVarObject header with a size field. Names, container slots and the interpreter stack hold pointers to these objects; whenever one is stored or dropped the interpreter does Py_INCREF or Py_DECREF. When the count reaches zero, the object's deallocator runs immediately, which releases its memory and decrefs everything it references.

Allocation has layers. Objects of up to 512 bytes go through pymalloc, a specialized allocator that carves memory into arenas, pools and size-class blocks to avoid slow general-purpose malloc calls and fragmentation; larger objects fall back to the system allocator. Free lists exist for hot types (floats, tuples, lists). Important consequence: freeing an object returns memory to pymalloc's pools, and arenas are released to the OS only when completely empty, so a process's RSS often does not shrink after you delete a big structure.

javascript

Trade-offs: reference counting gives prompt, deterministic cleanup and incremental cost (no stop-the-world pauses), but adds overhead to every assignment, cannot free reference cycles on its own (that is what the cyclic GC is for), and the non-atomic counter updates are the main reason the GIL exists. Tracing collectors (PyPy, JVM) have higher throughput on allocation-heavy code but non-deterministic destruction. Version-dependent: 3.12 introduced immortal objects (PEP 683), whose refcounts are never touched; the 3.13 free-threaded build uses a different scheme (biased and deferred reference counting) to remove the GIL; allocator arena and pool sizes have also changed across versions, so I do not quote exact numbers.

Common mistakes: relying on refcount-driven destruction for resource cleanup (it is a CPython behaviour, not a language guarantee; use with blocks or contextlib), assuming sys.getsizeof reports total memory (it is shallow, excluding referenced objects), and putting heavy logic in del. For leak hunting I use tracemalloc, gc.get_referrers and objgraph rather than guessing.

Scenario Questions

0-2 years experience

  1. 1What does sys.getrefcount(x) show for a freshly created list, and why is the number higher than you might expect?
  2. 2When is a file object opened without a with statement closed in CPython, and why should you not rely on that behaviour?

2-5 years experience

  1. 1After deleting a huge list, your script's memory usage does not drop in top. What can and can't you expect from the allocator, and what would you do about it?
  2. 2How would you find which objects are keeping a large data structure alive? Name specific tools and what each shows.

5-8 years experience

  1. 1A long-running service slowly leaks memory. Walk me through your diagnosis from symptom to root cause.
  2. 2Why are __del__ methods fragile for resource management, and what alternatives (context managers, weakref.finalize) do you prefer?

8+ years experience

  1. 1Explain the relationship between reference counting and the GIL, and how the free-threaded 3.13 build changes reference-count handling and single-thread performance.
  2. 2Pre-fork web workers gradually lose shared memory. How does reference counting cause copy-on-write page duplication, and which mitigations (gc.freeze, immortal objects) help?

Follow-up Questions

  • Why does sys.getrefcount always return at least 2 for a named object?
  • Why doesn't freeing a large list always reduce the process's memory usage?
Sharethis question

Share via WhatsApp, X, Facebook, LinkedIn or copy link. Open Graph preview enabled.