Life cycle of a new object without reference

2019-04-05 05:50发布

问题:

My question is related to:

  • Java: What is the purpose of creating an object in the heap with no reference
  • Java - Can objects which are executing methods be garbage-collected?

What actually happens when we have something like this in our code:

 (new SomeClass()).longMethod();

Is there still some sort of unnamed (strong ?) reference pointing to the newly created object on Heap put on Stack?

If nothing is on Stack, then how does Garbage Collector know to preserve the object for the duration of the method?

Is it possibly the same as

{ 
  // very local scope
  SomeClass throwAwayRef = new SomeClass();
  throwAwayRef.longMethod();
}

回答1:

You can look at the bytecode for insight:

   0: new           #16                 // class SomeClass
   3: dup
   4: invokespecial #18                 // Method SomeClass."<init>":()V
   7: invokevirtual #19                 // Method SomeClass.longMethod:()V
  • new actually allocates the object, a reference to which is pushed on the stack.
  • dup duplicates the top-of-stack; now the top two stack items are references to the newly created object.
  • invokespecial here calls the constructor of SomeClass, popping the stack; now the stack consists of just a single reference to our SomeClass instance. The instance is not GCed because a reference to it exists on the stack.
  • invokevirtual here calls longMethod. Again, the instance is not GCed because a reference to it still exists on the stack (and is popped after the method completes, after which it is eligible for GC).

(new SomeClass()).longMethod();

is not the same as

{ 
  // very local scope
  SomeClass throwAwayRef = new SomeClass();
  throwAwayRef.longMethod();
}

at the bytecode level, since the latter involves an astore and an aload. However, the two are certainly functionally equivalent. The SomeClass instance still becomes eligible for GC after longMethod completes (the stacks for the two snippets will look identical when invokevirtual is executed).


Reference:

  • Java bytecode instruction listings


回答2:

Yes,

new SomeClass().longMethod();

is effectively the same as, especially from a garbage collection standpoint:

{
    SomeClass throwAwayRef = new SomeClass();
    throwAwayRef.longMethod();
}

The in-line version has an implicit reference to the new object (on the stack). It becomes available for garbage collection as soon as the method call finishes.



回答3:

Yes, reference to the new object exists on the stack.

straight from Oracle:

To access a field, you can use a named reference to an object, as in the previous examples, or you can use any expression that returns an object reference. Recall that the new operator returns a reference to an object. So you could use the value returned from new to access a new object's fields:

int height = new Rectangle().height;

This statement creates a new Rectangle object and immediately gets its height. In essence, the statement calculates the default height of a Rectangle. Note that after this statement has been executed, the program no longer has a reference to the created Rectangle, because the program never stored the reference anywhere. The object is unreferenced, and its resources are free to be recycled by the Java Virtual Machine.

source: https://docs.oracle.com/javase/tutorial/java/javaOO/usingobject.html