[gclist] Question from a newbie

David Chase chase@world.std.com
Sun, 11 May 2003 22:08:31 -0400

At 05:42 PM 5/11/2003 -0400, I wrote:
>The specification, unfortunately, is a little vague in places,
>but I can tell you that in practice real programs don't
>appear to depend on these various optimizations not being

It occurred to me that the phrase "real programs" is a little
vague.  It includes a variety of programs that use AWT, various
J2EE servers and applications running within them, all the code
in Sun's libraries exercised by all these programs, and numerous
other applications.  The sort of things that they DO depend on
include (or DID include):

- some code in the native libraries for java.sql "knew" that
java.lang.String had some private fields with particular
interpretations, and used them.

- some code in some other native libraries "knew" about where
the actual file descriptors were stored in java.io, and used
that to obtain poor-man's-asynchronous I/O.

- some code in a database "knew" (by accident, because it had
never been tested the other way) that Sun's threads scheduled
in a particular way when a new thread was "started".

- some code in Sun's AWT native libraries (for Windows) actually
required that a JNI implementation NOT conform to the spec in
certain circumstances.

- some code does contain "dead loops" that are apparently used
for timing/delay purposes.  That's one reason why the loops were
left in the example program.  Another reason is that totally empty
loops aren't that common, except in benchmarks.  Yet another reason
is that code CAN detect when the optimizer removes an infinite
useless loop.  The easiest way to get by all these problems is
to just leave loops in.

- in one case, the specification clearly specifies a particular
behavior for type merges, and this is simply not what is implemented,
nor what most java-to-bytecode compilers generate.  Bytecode
programs that pass "verification" can nonetheless enter a state
where a static field, instance field, return value, or parameter
of declared type "Foo" holds a (non-null) value that is not an
instance of "Foo" (this can occur if Foo is an interface type).

These are real dragons, that caused a real, intended-to-be-
specification-conforming VM to have problems running "real"
code.  I have never seen real code affected by the GC and
finalization problems being discussed here.  It's certainly a
good idea to try to figure out exactly what GC means and when
finalization should happen, but in practice, the current
uncertainty appears not to be a serious problem.