/ˈsɜːrkjələr ˈrɛfərəns/
noun … “Objects referencing each other in a loop.”
Circular Reference occurs when two or more objects reference each other directly or indirectly, creating a loop in pointer or object references. In reference counting systems, circular references can prevent objects from being deallocated because their reference counts never reach zero, leading to memory leaks. Proper detection or use of weak references is necessary to break these cycles.
Key characteristics of Circular Reference include:
- Mutual referencing: objects hold references to each other in a loop.
- Memory retention risk: reference-counted systems cannot automatically reclaim memory involved in the cycle.
- Detection complexity: requires graph traversal or weak reference usage to identify and resolve.
- Impact on garbage collection: modern tracing collectors can handle circular references, unlike simple reference counting.
- Common in linked structures: graphs, doubly-linked lists, and observer patterns are prone to cycles.
Workflow example: Circular reference in Python:
class Node {
def __init__(self, name):
self.name = name
self.partner = None
}
a = Node("A")
b = Node("B")
a.partner = b
b.partner = a -- Circular reference created
Here, a and b reference each other, forming a cycle. Without using weak references or a garbage collector that can detect cycles, these objects may remain in memory indefinitely.
Conceptually, a Circular Reference is like two friends holding hands in a loop: unless someone releases, the loop never breaks, and both remain connected permanently.
See Pointer, Reference Counting, Weak Reference, Garbage Collection, Memory Leak.