Is unused object available for garbage collection when it's still visible in stack?

前端 未结 5 1434
心在旅途
心在旅途 2020-12-30 01:44

In the following example there are two functionally equivalent methods:

public class Question {

    public static String method1() {
        String s = new          


        
相关标签:
5条回答
  • 2020-12-30 02:09

    No, because your code could conceivably retrieve it and do something with it, and the abstract JVM does not consider what code is coming ahead. However, a very, very, very clever optimizing JVM might analyze the code ahead and find that there is no way s1 could ever be referenced, and garbage collect it. You definitely can't count on this, though.

    0 讨论(0)
  • 2020-12-30 02:12

    If you're talking about the interpreter, then in the second case S1 remains "referenced" until the method exits and the stack frame is rolled up. (That is, in the standard interpreter -- it's entirely possible for GC to use liveness info from method verification. And, in addition (and more likely), javac may do its own liveness analysis and "share" interpreter slots based on that.)

    In the case of the JITC, however, an even mildly optimizing one might recognize that S1 is unused and recycle that register for S2. Or it might not. The GC will examine register contents, and if S1 has been reused for something else then the old S1 object will be reclaimed (if not otherwise referenced). If the S1 location has not been reused then the S1 object might not be reclaimed.

    "Might not" because, depending on the JVM, the JITC may or may not provide the GC with a map of where object references are "live" in the program flow. And this map, if provided, may or may not precisely identify the end of the "live range" (the last point of reference) of S1. Many different possibilities.

    Note that this potential variability does not violate any Java principles -- GC is not required to reclaim an object at the earliest possible opportunity, and there's no practical way for a program to be sensitive to precisely when an object is reclaimed.

    0 讨论(0)
  • 2020-12-30 02:21

    VM is free to optimized the code to nullify s1 before method exit (as long as it's correct), so s1 might be eligible for garbage earlier.

    However that is hardly necessary. Many method invocations must have happened before the next GC; all the stack frames have been cleared anyway, no need to worry about a specific local variable in a specific method invocation.

    As far as Java the language is concerned, garbages can live forever without impact program semantics. That's why JLS hardly talks about garbage at all.

    0 讨论(0)
  • 2020-12-30 02:21

    in first of them string "s1" is clearly available for garbage collection before return statement

    It isn't clear at all. I think you are confusing 'unused' with 'unreachable'. They aren't necessarily the same thing.

    Formally speaking the variable is live until its enclosing scope terminates, so it isn't available for garbage collection until then.

    However "a Java compiler or code generator may choose to set a variable or parameter that will no longer be used to null to cause the storage for such an object to be potentially reclaimable sooner" JLS #12.6.1.

    0 讨论(0)
  • 2020-12-30 02:27

    Basically stack frames and static area are considered as roots by GC. So if object is referenced from any stack frame its considered alive. The problem with reclaiming some objects from active stack frame is that GC works in parallel with application(mutator). How do you think GC should find out that object is unused while method is in progress? That would require a synchronization which would be VERY heavy and complex, in fact this will break the idea of GC to work in parallel with mutator. Every thread might keep variables in processor registers. To implement your logic, they should also be added to GC roots. I cant even imagine how to implement it.

    To answer you question. If you have any logic which produces a lot of objects which are unused in the future, separate it to a distinct method. This is actually a good practice.

    You should also take int account optimizations by JVM(like EJP pointed out). There is also an escape analysis, which might prevent object from heap allocation at all. But rely your codes performance on them is a bad practice

    0 讨论(0)
提交回复
热议问题