Why is the "invisible" object not immediately assembled?

I just read this article: The Truth About Garbage Collection

Section "A.3.3 Invisible" explains how and when an object goes into invisible state.

In the code below, the object assigned to the variable foo will become invisible after exiting the try/catch and will remain on a strong link until the run method exits (which will never happen, since the while loop runs forever).

 public void run() { try { Object foo = new Object(); foo.doSomething(); } catch (Exception e) { // whatever } while (true) { // do stuff } // loop forever } 

This article says:

However, an effective JVM implementation is hardly a null reference when it goes beyond the scope.

Why is this not effective?

My attempt at explanation is as follows:

Say that the stack for this method contains four elements, and now an invisible object is at the bottom.
If you want to instantly assemble an object, you will need to place and save three elements, pop and drop the fourth element, and then return the three still valid elements back to the stack.
If you collect an invisible object after the control flow leaves the run method, the virtual machine could just put all four elements and discard them.

+4
source share
2 answers

Local variables are not in the operand stack, but in the area of ​​local variables in the activation frame that is accessed, in the case of referencing astore codes with aload and astore and resetting the local variable, no pressing and popping is required.

Zeroing is inefficient because it is not required:

  • this will not cause an immediate garbage collection cycle.
  • zero can soon be overwritten with another value, which is dictated by the logic of the program.
  • Leaving the scope means that the local variable is no longer part of the root collection set. As such, the value that it held immediately before leaving the sphere of action β€” zero or a valid reference β€” is not significant; it will not be considered in any way.

EDIT:

Some comments on the last statement.

Indeed, there are no areas at the bytecode level, and the local variable slot can remain part of the root set until the method returns. Of course, the JVM implementation can determine when the local slot of a variable is dead (i.e., all possible ways to return the method either do not have access to the variable or are repositories) and do not consider it part of the root set, but this is by no means required for this.

+3
source

The simplest answer: b / c is ineffective.

There are many garbage collection algorithms, and some of them can be aggressively collected. Some compilers do allocations on the stack, but the most obvious in your case is: doSomething() can actually (leak) a reference to an object elsewhere.

0
source

Source: https://habr.com/ru/post/1382051/


All Articles