title: Why do garbage collectors wait before deallocating?
body: <p>I have a "why does it work that way?" question about garbage collection (any/all implementations: Java, Python, CLR, etc.).  Garbage collectors deallocate an object when it is no longer in any scope; the number of references pointing to it is zero.  It seems to me that a framework could deallocate as soon as the number of references reaches zero, but all implementations I've encountered wait a while and then deallocate many objects at a time.  My question is, why?</p>
  
  <p>I'm assuming that the framework keeps an integer for each object (which I think Python does, because you have to call <code>PyINCREF</code> and <code>PyDECREF</code> when writing extension modules for it in C; presumably these functions modify a real counter somewhere).  If so, then it shouldn't take any more CPU time to eliminate the object the moment it goes out of scope.  If it takes x nanoseconds per object now, then it would take x nanoseconds per object later, right?</p>
  
  <p>If my assumption is wrong and there is no integer associated with each object, then I understand why garbage collection waits: it would have to walk the graph of references to determine the status of each object, and that calculation takes time.  Such a method would consume less memory than the explicit reference-count method, but I'm astonished that it's quicker or is the preferred method for other reasons.  It sounds like a lot of work.</p>
  
  <p>From a programming point of view, it would be nice if objects deallocated immediately after they go out of scope.  Not only could we rely on destructors being executed when we want them to be (one of the Python gotchas is that <code>__del__</code> is not called at a predictable time), but it would become much easier to memory-profile a program.  <a href="https://stackoverflow.com/questions/7114661/why-does-java-wait-so-long-to-run-the-garbage-collector">Here's an example</a> of how much confusion this causes.  To my mind, the benefits of programming in a deallocate-right-away framework are so great that there must be some good reason why all the implementations I've heard of wait before deallocating.  What is that benefit?</p>
  
  <p>Note: if the walk over the graph of references is only needed to identify circular references (a pure reference count can't), then why not a hybrid approach?  Deallocate objects as soon as their reference count hits zero and then also do periodic sweeps to look for circular references.  Programmers working in such a framework would have a performance/determinism reason to stick to non-circular references as much as is feasible.  It's often feasible (e.g. all data are in the form of JSON objects with no pointers to parents).  Is this how any popular garbage collectors work?</p>