Short answer
Local primitives and object references live on the per-thread stack and are reclaimed instantly when the frame pops; the objects they point to live on the shared heap and are reclaimed only by the garbage collector once unreachable.
Explanation
This is why an object 'going out of scope' is not immediately freed — it is just eligible for GC. Modern JITs can use escape analysis to scalar-replace or stack-allocate objects that never escape a method, avoiding heap allocation entirely.
Common mistakes
- Saying all objects are always on the heap without mentioning escape analysis may scalar-replace them.
- Confusing the call stack with the GC-managed heap.