Workaround for JDialog me
To: comp.lang.java.gui
I just submitted a bug report on a memory leak that I discovered in 1.6 (I
tested with 1.5 and there is no memory leak). What I am wondering is if
anyone has encountered this bug and if so if there is any better workaround
which I will describe shortly?
Basically one would first create a JFrame and then have a modal child dialog
(e.g,. PrimaryChildDialog) hanging off of it and then create another modal
child dialog (e.g., SecondardChildDialog) which hangs off the first modal
child dialog. Now one would close/dispose SecondaryChildDialog and then
close/dispose PrimaryChildDialog and then set PrimaryChildDialog to null.
Now if one repeats the above process n times one would see n
PrimaryChildDialog objects occupying memory (i.e.,
PrimaryChildDialog.finalize method never gets called and it is also returned
in the array of Window objects from the Windows.getWindows() method).
For example here is a code snippet for creating/showing and then disposing
PrimaryChildDialog:
public void openPrimaryChildDialog ()
{
fPrimaryChildDialog = new PrimaryChildDialog(getFrame (),
"Primary Child Dialog...", true);
fPrimaryChildDialog.openDialog ();
fPrimaryChildDialog.dispose ();
fPrimaryChildDialog = null;
// Note: there should be a better way of causing Java to IMMEDIATELY
// release the fPrimaryChildDialog resource! ==> Ugh!
getFrame ().dispose ();
Runtime.getRuntime ().runFinalization ();
getFrame ().setVisible (true);
}
In Java 1.5 PrimaryChildDialog's finalize method is correctly called each
time but in 1.6 there are n instances of PrimaryChildDialog and its finalize
method is never called. Oh yes, I got the following cool piece of code to
guarantee that the memory was indeed flushed which I called everytime I
disposed of PrimaryChildDialog:
private void flushMemory(PrintStream pPrintStream)
{
pPrintStream.println ("\nFlush memory begin:");
//Use a vector to hold the memory.
Vector v = new Vector();
int count = 0;
//increment in megabyte chunks initially
int size = 1048576;
//Keep going until we would be requesting
//chunks of 1 byte
while(size > 1)
{
try
{
for (; true ; count++)
{
//request and hold onto more memory
v.addElement( new byte[size] );
}
}
//If we encounter an OutOfMemoryError, keep
//trying to get more memory, but asking for
//chunks half as big.
catch (OutOfMemoryError bounded){size = size/2;}
}
//Now release everything for GC
v = null;
//and ask for a new Vector as a new small object
//to make sure garbage collection kicks in before
//we exit the method.
v = new Vector();
// Let's run gc anyhow...
Runtime.getRuntime ().gc ();
pPrintStream.println ("\nFlush memory end.");
}
The only workaround that I could think of is to minimize the memory impact
by calling the JDialog's getContentPane().removeAll () method as well as any
hard references in the class which I extended so that at least those items
can be garbage collected.
Does anyone have any better workaround and has anyone encountered this
problem?
If anyone is interested I can send the small test case (4 small Java files)
that I just submitted to Sun.
Karl
---
* Synchronet * The Whitehouse BBS --- whitehouse.hulds.com --- check it out free usenet!
--- Synchronet 3.15a-Win32 NewsLink 1.92
Time Warp of the Future BBS - telnet://time.synchro.net:24