Is the stack garbage collected in Java?

2019-01-21 15:58发布

问题:

The heap memory is garbage collected in Java.

Is the stack garbage collected as well?

How is stack memory reclaimed?

回答1:

The memory on the stack contains method-parameters and local variables (to be precise: the references for objects and variables itself for primitive types). That will be automatically removed if you leave the method. If the variables are references (to objects) the objects itself are on the heap and handled by the garbage collector.

So the stack isn't garbage collected in the same way as the heap, but stack is a form of automatic memory-management in it's own (which predates garbage collection).

A more detailed answer is given by Thomas Pornin, look into that for more details.



回答2:

The stack is not garbage collected in Java.

The stack allocated for a given method call is freed when the method returns. Since that's a very simple LIFO structure, there's no need for garbage collection.

One place where the stack and garbage collection interact is that references on the stack are GC roots (which means that they are the root references from which reachability is decided).



回答3:

The stack could be garbage collected. However, in most JVM implementations, it is handled as, well, a "stack", which by definition precludes garbage collection.

What we call the stack is the accumulation of method activation contexts: for each invoked method, this is the conceptual structure which contains the method arguments, local variables, a hidden pointer to the context for the calling method, and a slot to save the instruction pointer. The activation context is not accessible as such from the Java language itself. A context becomes useless when the method exits (with a return or because of a thrown exception). It so happens that when a method A calls a method B, it is guaranteed that when A regains control, the context for B has become useless. This implies that the lifetime of the context for B is a subrange of the lifetime of the context for A. Therefore, activation contexts (for a given thread) can be allocated with a LIFO ("Last In, First Out") discipline. In simpler words, a stack: a new activation context is pushed on top of the stack of contexts, and the context on top will be the first to be disposed of.

In practice, the activation contexts (also called stack frames) are concatenated, in stack order, in a dedicated area. That area is obtained from the operating system when the thread is started, and the operating system gets it back when the thread terminates. The top of the stack is designated by a specific pointer, often contained in a CPU register (this depends on whether the JVM is interpreting or compiling code). The "pointer to caller's context" is virtual; the caller's context is necessarily located just below in stack order. The GC does not intervene: the area for the stack is created and reclaimed synchronously, from the thread activity itself. This is also how it works in many languages such as C, which do not have a GC at all.

Now nothing prevents a JVM implementation from doing otherwise, e.g. allocating activation contexts in the heap and having them collected by the GC. This is not usually done in Java Virtual Machines since stack allocation is faster. But some other languages need to do such things, most notably those which play with continuations while still using a GC (e.g. Scheme and its call-with-current-continuation function), because such games break the LIFO rule explained above.



回答4:

The stack part of the memory works just like a "stack". I know it sounds bad, but that's exactly how it works. Data is added to the top, on top of each other (pushed onto the stack) and is automatically removed from the top (popped off the stack) as your program runs. It is not garbage collected - and it doesn't need to be since that memory is automatically reclaimed once data is popped off the stack. And when I say reclaimed I don't mean it gets de-allocated - it's just that the location in the stack memory where the next data will be stored is decreased, as data is popped off.

Of course that's not to say that you don't need to worry at all about the stack. If you run a recursive function many times it will eventually use up all the stack space. The same if you call many functions, especially if they have many parameters and/or local variables.

But the bottom line is that the memory of the stack is used and reclaimed as functions enter and leave scope - automatically. So at the end of your program's execution all the stack memory would be free and then released back to the operating system.



回答5:

If you refer to the memory used on the stack, it is not garbage collected.
The java virtual machine uses explicit bytecode instructions to reserve and release memory on the stack, these instructions are generated by the compiler and manage the lifetime of primitives like int,boolean,double and object-references on the stack.
There have been plans to implement a so called tail call optimisation, which would remove some entries from the stack once it is known that they are no longer used, but I don't know any jvm which already supports this.
So no there is no garbage collection for the stack itself, only the compiler generated push and pop instructions to manage the memory use.

The stack itself is part of a thread. The stack is allocated when the thread object is created and garbage collected after the thread terminated and the thread object is no longer referenced.



回答6:

All objects in Java are allocated on the heap. (At least as far as the spec goes, the actual implementation may allocate them on the stack if they transparently behave as if they were on the heap.)

Exactly what is collectible is a bit subtle. If the only reference to an object is in a single stack frame, and it can be shown that reference will not be used again, then the object may be collected. If the object is only used to read a field, then that field read may be optimised forward and the object collected earlier than you might expect.

This doesn't usually matter unless you are using finalisers (or presumably References). In that case you should be careful and use locks/volatile to enforce a happens-before relationship.

When threads stop, then typically the entire stack will be deallocated.



回答7:

Everything located on stack is treated as global roots by a garbage collector. So, yes, you definitely can say that stack is "garbage collected".



回答8:

No one, data is pushed and popped from stack as you have inner variables in methods, during method calls, etc. You don't need to care about this.



回答9:

No. The stack is not garbage collected in Java. Each thread has its own stack and contains :

  1. Method specific values (which are short lived) and
  2. References to the objects, created on heap, and are being referred to by the method

These values are pushed as stack frames to the stack for every method call. Since the stack follows 'Last-in First-out' order, at the end of every method call, each stack frame containing all the method specific data and the references to objects, if any, is popped out.

Hence, data in stack are automatically cleaned once the method/program goes out of scope.