Extend Object

Today, a client needed this solution, so I thought I'd write it up.

A few years back, some friends and I wrote some Java code for MTV.com. Fairly late into the game, we discovered that memory was not being cleaned up correctly. We were expecting the GC to do its job, and it wasn't.

We struggled hard to solve the problem. We were writing in Java 1.02, for use in Navigator and IE on PCs and MACs. After much hard work, we discovered that the GC worked a lot better if we made our classes explicitely extend Java's Object class. We then solved our memory problem by adding finalize() methods to our classes, setting member variables to null inside those finalize() methods, and then explicitly telling the GC, upon exiting our app, to do its job. We certainly did not want to write all that code (which reminded us of writing destructors in C++), but we had to solve the problem.

-JoshuaKerievsky


Okay, my memory's bad. Certainly, in JDK1.1 and higher, when you define a class, if you don't give it a superclass, it extends Object.

Was this not the case in JDK1.02 ?

I also don't understand the stuff about "exiting the app" ? If the JVM is shutting down (one possible meaning), then the resources should make it back (e.g. this isn't a JavaIdiom, but a way to cope with a particularly buggy JVM that isn't releasing system resources). If it's not a reference to shutting down the JVM, what does "exiting the app" mean ? Is this something that applies when two or more applets share a JVM ?

It seems to me that this is a workaround for a buggy JVM, not a JavaIdiom

WilliamGrosso


The GC, in many JVMs (JDK 1.0.x & 1.1.x), doesn't always collect the garbage when you'd expect it to. This can yield some strange behavior in both applets and applications.

Exiting an "applet" in a browser context can mean many things so I'll clarify what I mean (and should have done so in the first place). In this case, it did not mean exiting the browser, but closing a browser window and loading a goodbye.html page into another browser window. Memory was not being cleaned up correctly after this "exit" and whatever was being kept around, made a user's surfing experience exceedingly slow. So, even though our classes did implicitely extend Object (yes, this also applies to JDK 1.02), we found that we needed to explicitely extend Object to make the GC do its thing.

Is this a JavaIdiom I would tend to agree with you that it is not. But I do believe it is useful knowledge, so I wonder where it belongs?

--JoshuaKerievsky


I am still lost. (Is anyone else?) Are you saying that explicitly including the text "extends Object" in your declaration of a class produces something different than using no extends clause? Or do you mean something else when you speak of explicitly extending Object? --KielHodges


Yes, if you experience oddness with respect to memory cleanup in Java, consider writing code in the following way:

public class XYZ extends Object { ...

  public void finalize()
  {
    // set stuff to null here
  }

... }

Then, when you are ready to exit your applet or application, call

Runtime r = Runtime.getRuntime(); r.gc();

Is that clear now?

--JoshuaKerievsky


The GC is deliberately ill-defined about how it does its job. There's no guarentee about when particular objects get collected (except, optionally, when the JVM is closed down).

As I understand it, most implementations are conservative with respect to the stack. That is, although information about which stack slots are integers and which are references is available to the verifier at load time, it's been lost by the time the GC is involved. So if an integer happens to have the same value as a reference, it can keep the reference alive longer than expected.

You also get situations where stack variables retain their values between routine calls. The verifier prevents user code from accessing the uninitialised slot, but the GC can see the old slot value. This is more likely to happen because it doesn't rely on a chance match between an integer and a reference value.

In a situation like this, making random changes to program code can affect what the GC does. Eg a trivial re-ordering local variables might cause the stray value to be over-written earlier without affected the program's official semantics. The behaviour may also vary between JVM implementations - MSIE and Netscape in particular have different GCs.

I suspect ExtendObject is such a random change. I don't really see how it follows from either of the above two paragraphs, but often objects with non-trivial finalisers are treated differently to normal objects so that might have something to do with it. If so I'd expect the finaliser is what makes the difference, not extending from Object. Is it also possible that in the clear-up, you disposed some O/S resource that wasn't being disposed before, like a bitmap handle or a display context? -- DaveHarris


I don't know whether this is related, but it is good to know that

 System.runFinalizersOnExit(true);

causes finalizers to be run on applet/application exit. The (stupid, IMHO) default is not to run them. It took us a while to figure this out. -- MarnixKlooster


EditText of this page (last edited September 4, 1998) or FindPage with title or text search