What destroys the local variable in java?

The garbage collector - the Reaper, as it's sometimes known - runs on its own schedule, and collects objects which are out of reference. The local variables, of course, cannot be referenced after the method exits, because they are out of scope, so to your program they are dead*, but they still exist on the heap until the GC runs.

Under normal circumstances (and most abnormal ones) you do not need to tell the Reaper when to do its work. It will come, silently, when it is needed, and carry away those things which are no longer needed. This is one of the major advantages of working in a high-level language: it's safe to assume that you never need to think about things like managing deallocation of dead objects. You can just toss them over your shoulder and know that they will never bother you. I suppose there are some high-performance, high-demand applications that need to fiddle with the GC, but that's an optimization which should always be presumed premature unless you have really good evidence to the contrary.

*except, of course, for local variables which are returned to the calling function, which may become local variables in that scope and gain a little more lease on life. In general, the rule is: if some part of your code still cares about the variable, it will not be garbage collected, and if no part of your program cares about it, then you don't need to think about it.


Method local variables (or just "local variables" as they are normally called) are allocated on each thread's stack. The variables themselves are not subject to garbage collection. They are reclaimed automatically when the method call terminates (normally or abnormally)1.

Objects are another matter. Objects (including arrays) are normally2 allocated on the heap, and they are subject to garbage collection.


So what about an object (or array) that is allocated by a method and assigned to local variable?

First of all, the local variable holds a reference to the object. The object is stored in the heap (see above).

When the garbage collector runs (and you generally don't know when that will be!) it will check any existing local variables for method calls that are still in progress. It the variables contain references to objects, those objects are added to the list of objects to be kept ... and they are checked for references to other objects, and so on.


So, in summary, local variables are destroyed automatically when the method call ends, but the objects that those variables refer to will continue to exist until the GC (eventually) figures out that they are unreachable.


1 - We need to consider local variables that are accessed from an inner class or lambda that is declared within the scope of the variable. The class of lambda instance may passed somewhere so that it can be used after the method returns. In this case, the you would think that the local variable needs to live after method has returned. In reality, what happens is that the local variable is copied to a synthetic field in the object that represents the inner class or lambda instance. The class / lambda then uses the value in the field. The original variable does disappear when its method terminates.

2 - Recent Hotspot JIT compilers have an optional optimization called "escape analysis" that is used to find cases where objects created by a method call can be allocated on the thread's stack. This is not enabled by default. If an object is allocated on the stack, then it will be reclaimed when the method call ends. The GC is not involved.

3 - You said: "GC is triggered when Eden or Long-generation blocks are overflowed (minor/major GC) etc...". This is not necessarily so. Some of the low-pause collectors are triggered before the respective spaces fill up. However, this doesn't alter any of the above.