Garbage collection reclaims unreachable objects. See why a cycle defeats pure reference counting, what Python del removes, and how collection affects latency.
Garbage collection and pauses
Garbage collection is automatic memory reclamation by a language runtime: it identifies objects the program can no longer reach and makes their memory available for reuse. In a quant service, that bookkeeping can affect when a market-data handler or risk calculation finishes, even when its mathematical work is unchanged. Collection policy therefore matters to both memory use and latency jitter, the variation in response time. Oracle's garbage-collection introduction describes the memory-management work involved.
The key distinction is between an object the application no longer wants and an object the runtime can prove is unreachable. A cache that still refers to an obsolete market snapshot keeps it reachable. A collector cannot infer that the snapshot has become economically irrelevant.
Follow the references, not the variable names
Think of memory as a directed graph. Objects are nodes; strong references are arrows. A root is an entry point the running program can still use, such as a live reference in an active function or global state. Following arrows from the roots identifies reachable objects. Here, every arrow is a strong reference; weak references and runtime bookkeeping are outside the simplified model.
Suppose two fictional objects, A and B, refer to one another, and the program initially holds one additional reference to A. A has two incoming references: one from the root and one from B. B has one, from A. Both are reachable.
Now remove the only root reference. A and B still refer to each other, so each has one incoming reference. Yet there is no longer a path from the program's roots to either object.
Simplified strong-reference graph: before the root edge is removed, A has count 2 and B has count 1, and both are reachable. Afterwards each count is 1, but neither object is reachable from a root.
Removing the only root edge leaves an unreachable cycle with positive internal reference counts. Counts describe this illustrative graph, not measured interpreter reference counts.
This exposes the difference between two collection ideas:
Pure reference counting decrements counts as references disappear and reclaims objects whose counts reach zero. In this cycle, neither count reaches zero, so that rule alone cannot reclaim A or B.
Tracing starts from roots and follows references. A traversal reaches neither object after the root edge disappears, so it can identify both as unreachable despite their positive internal counts.
These are mechanisms, not mutually exclusive language labels. CPython supplements reference counting with a cyclic garbage collector, which can identify unreachable reference cycles. The CPython collector design explains why that extra machinery is needed. Reclamation still follows the runtime's rules: finalization may resurrect an object, and some extension types can leave uncollectable garbage. Python's gc documentation describes these qualifications; a cycle is not an unconditional promise of immediate cleanup.
What Python's del actually removes
In Python, deleting a name removes that name's binding, as specified by the del statement. If another name, container or cache still holds the object, removing one name does not make the object unreachable. Even removing the final external name can leave the internal cycle shown above.
Python's data model separates language semantics from CPython's implementation and warns against relying on immediate finalization. Files and similar resources need explicit cleanup through their supported close operation or context manager. Waiting for garbage collection is a poor way to decide when such a resource should be released.
Disabling CPython's automatic cyclic collector does not disable reference counting. It can allow unreachable cycles to accumulate, so it is not a general switch for removing memory-management costs. The gc module overview states this distinction. These implementation observations were checked against the official documentation on 29 October 2026; other Python implementations and builds can differ.
A pause is a scheduling cost
A stop-the-world pause suspends application execution while the collector performs work requiring that suspension. Parallel collection uses multiple collection workers; concurrent collection overlaps some collection work with application execution. Parallel work alone does not establish overlap with the application. Oracle's collector descriptions illustrate why the selected collector matters.
For a fictional quote service, a pause can delay processing of a new price or cancellation request. That is a practical consequence of suspending the service, not a measured pause duration or trading-profit estimate. A concurrent collector also consumes computational resources; its name alone does not establish a pause-free response-time guarantee.
Throughput, memory footprint and responsiveness are different objectives. A configuration that completes more work over a long run can still produce unacceptable individual delays. Oracle's performance discussion treats latency and throughput separately and explains why heap choices involve trade-offs.
A useful investigation connects three observations:
What is retained? Inspect reference paths to unexpectedly long-lived objects, including caches. Reachable but unwanted objects need an application-lifetime fix.
When does collection happen? Record collection events using the actual runtime's diagnostics and compare their timestamps with slow requests. Coincidence motivates investigation; it does not by itself isolate causation.
What changed under the same workload? Compare response-time distributions, memory use and completed work after a change. Reducing temporary allocations, changing retention or selecting a different collector has costs that need measurement.
Those are diagnostic choices, not a universal instruction to disable collection or replace a language. Memory ownership addresses how responsibility for an object's lifetime is represented; collection policy addresses how a runtime discovers and reclaims garbage. Neither label supplies an end-to-end latency guarantee.
For the names-and-objects foundation, Collections explains aliases and shallow copies. Its public preview is available without an account; the full lesson is free with sign-in. Profiling and Optimisation develops controlled timing and bottleneck diagnosis. It has a public preview; the full lesson requires membership. It provides a measurement foundation, rather than a collector-specific tuning procedure.