G
Guest
Hi,
I'm working on an applet that has a GDI object leaking issue; in this
applet, a second thread draws something (using java.awt.Graphics's
methods ) on the main Panel dynamically. But when running under Sun JVM,
every time the drawing is called, one more GDI object is created and
memory is allocated for the GDI object, they are not released when the
thread exits and all its objects are dereferenced. So after a while,
the Windows GUI will be very slow and erratic, for there are so many
GDI objects.
The problem does not happen on Microsoft JVM.
To see the problem, you can use the following simplified applet code,
start the applet in a browser or appletviewer that uses Sun JVM on Windows.
Open Windows Task Manager, turn on the "GDI objects" column in the
"processes" tab. You can see the browser's process's memory and GDI
object count keep increasing. And after some minutes, when there are
too many GDI objects in the OS, the WIndows GUI becomes very slow and
erratic.
I tried cleaning up the resource using System.gc(),
System.runFinalization(), nullifying the Graphics object, forcing
Graphics.dispose() method(); and I tried different ways to implement
the thread ( using Runnable ), start the thread at different places,
and different ways to stop the thread; also I tried letting the main
thread create the Graphics object then pass it down to the second
thread, and using Toolkit.sync() method.
None of these worked.
Any one have any idea how to fix or workaround this problem?
Source code is below, I will post the compiled classes later.
thanks
---------- BEGIN SOURCE ----------
//Run this applet using SUN JVM under Windows, and open //the Task manager with
"GDI objects" column on.
//You will see the GDI object leak.
//And after some minutes the GUI of Windows will become slow and erratic.
//It's the Graphics method in the secondary thread causing the problem.
//Microsoft JVM does not have this problem.
import java.applet.*;
import java.awt.event.*;
import java.awt.*;
public class Table extends Applet implements Runnable{
public void init() {}
public void start() {
Thread t = new Thread( this );
t.start();
}
public void run() {
while(true) {
Graphics gr = null;
try {
gr = getGraphics();
// This one does NOT cause the leak.
// And removing this one does not help.
gr.drawLine(0, 10, 10, 0 );
} finally { gr.dispose(); }
try { Thread.sleep(20); } catch (InterruptedException e) { }
Flash f = new Flash();
f.t = this;
f.start();
try { Thread.sleep(30); } catch (InterruptedException e) { }
}
}
private class Flash extends Thread{
public Table t;
public synchronized void run(){
Graphics gr = null;
try {
gr = t.getGraphics();
gr.drawLine(0,0,10,10); // This one DOES cause the leak.
} finally { gr.dispose(); }
gr = null;
}
};
}
---------- END SOURCE ----------
I'm working on an applet that has a GDI object leaking issue; in this
applet, a second thread draws something (using java.awt.Graphics's
methods ) on the main Panel dynamically. But when running under Sun JVM,
every time the drawing is called, one more GDI object is created and
memory is allocated for the GDI object, they are not released when the
thread exits and all its objects are dereferenced. So after a while,
the Windows GUI will be very slow and erratic, for there are so many
GDI objects.
The problem does not happen on Microsoft JVM.
To see the problem, you can use the following simplified applet code,
start the applet in a browser or appletviewer that uses Sun JVM on Windows.
Open Windows Task Manager, turn on the "GDI objects" column in the
"processes" tab. You can see the browser's process's memory and GDI
object count keep increasing. And after some minutes, when there are
too many GDI objects in the OS, the WIndows GUI becomes very slow and
erratic.
I tried cleaning up the resource using System.gc(),
System.runFinalization(), nullifying the Graphics object, forcing
Graphics.dispose() method(); and I tried different ways to implement
the thread ( using Runnable ), start the thread at different places,
and different ways to stop the thread; also I tried letting the main
thread create the Graphics object then pass it down to the second
thread, and using Toolkit.sync() method.
None of these worked.
Any one have any idea how to fix or workaround this problem?
Source code is below, I will post the compiled classes later.
thanks
---------- BEGIN SOURCE ----------
//Run this applet using SUN JVM under Windows, and open //the Task manager with
"GDI objects" column on.
//You will see the GDI object leak.
//And after some minutes the GUI of Windows will become slow and erratic.
//It's the Graphics method in the secondary thread causing the problem.
//Microsoft JVM does not have this problem.
import java.applet.*;
import java.awt.event.*;
import java.awt.*;
public class Table extends Applet implements Runnable{
public void init() {}
public void start() {
Thread t = new Thread( this );
t.start();
}
public void run() {
while(true) {
Graphics gr = null;
try {
gr = getGraphics();
// This one does NOT cause the leak.
// And removing this one does not help.
gr.drawLine(0, 10, 10, 0 );
} finally { gr.dispose(); }
try { Thread.sleep(20); } catch (InterruptedException e) { }
Flash f = new Flash();
f.t = this;
f.start();
try { Thread.sleep(30); } catch (InterruptedException e) { }
}
}
private class Flash extends Thread{
public Table t;
public synchronized void run(){
Graphics gr = null;
try {
gr = t.getGraphics();
gr.drawLine(0,0,10,10); // This one DOES cause the leak.
} finally { gr.dispose(); }
gr = null;
}
};
}
---------- END SOURCE ----------