Re: Garbage collector quiz

From: Chris Uppal (chris.uppal_at_metagnostic.REMOVE-THIS.org)
Date: 10/12/04


Date: Tue, 12 Oct 2004 09:02:12 +0100

Razvan wrote:

> I choosed 10, the right answer is 11.

I think you meant that the other way around ?

> The reason for this is the fact
> that even if the variable tmp is out of scope it is STILL holding a
> reference to the last 'tmp' string. Is that true ?!!

Joona is correct, but I wanted to expand on this a little.

There are several issues that can confuse this.

One is that, as Joona says, some or all of the temporary Strings may already
have been garbage collected, rather than still merely being "eligible" for
collection.

Another is that the compiler is within its rights (as I read the spec) to
re-write the code as if it said:

    public static void main(String args[])
    {
        System.out.println("CDummy.");
        for(int ii=10; ii>=0; ii--)
        {
            String tmp = Integer.toString(ii);
            System.out.println(tmp);
            tmp = null;
        }
        System.out.println("END");
}

or the equivalent (which is not expressible in Java) where the store used for
the "tmp" variable is overwritten after the inner loop has completed.

So it is possible that /all/ the temporary Strings have become eligible for GC
by the time we read the final println("END").

However, what the question is presumably trying to get at is that, if you
ignore the above complexities, then in a typical implementation the last
temporary String is not available for collection until main() returns.

The reason for that is quite simple, it's that although Java-the-language has a
concept of local variables with a scope smaller than a whole method, the
language understood by the JVM (i.e. the classfile format) does not have that
concept. In "JVM-speak" (never forget that JVM bytecodes are a high-level
language too -- at least as high-level as Java -- so the Java "compiler" should
really be called a translator) there are no named local variables, just a fixed
size list of "slots" which hold values that are local to each method
invocation. Those slots come into existence when the method is called, and
their contents only become eligible for GC (typically) when the method returns.

So the Java compiler (sorry, "translator") has used one of the slots to hold
the values of "tmp", and -- unless it either takes special steps to null-out
that slot before the method returns (which no standard compiler does AFAIK), or
happens to re-use that slot for some other variable -- then the last value of
"tmp" will still be in that slot until the method returns.

    -- chris



Relevant Pages

  • Re: derangement: coding review request
    ... > there is no good buys_for in scope. ... "tmp" or similar names in macros and wondering why it went wrong ... > No point in complicating the interface of SWAP. ... > The only valid objection to the original form is that C99 deprecates it. ...
    (comp.lang.c)
  • Re: portable typeof macro
    ... but wouldn't such a macro be limited to only ... one appearance per variable scope? ... that's why it's all wrapped up in a {block scope}. ... I didn't even think about the scope of tmp. ...
    (comp.lang.c)
  • Watch Window not showing Out of scope variables??
    ... When I step through this code with the debugger, ... and error:indentifier 'tmp' out of scope. ... String ^tmp; ...
    (microsoft.public.dotnet.languages.vc)
  • Re: Drop temporary tables
    ... Although #tmp is supposed to be handled/dropped by the system when it's out ... of scope, it's better to do the clean up yourself. ... create proc usp ...
    (microsoft.public.sqlserver.programming)
  • Re: very strange effect with anonymous delegates (.net 2.0)
    ... > the view of the sourcecode since "PropertyInfo prop" is a readonly ... > they should at least throw a compiler error when a foreach iterator is ... at the outermost scope of the local variables that are used within the anon ... It obviously can't do it within the scope as the outermost one ...
    (microsoft.public.dotnet.languages.csharp)