I created a GUI (Eclipse Wizard) where a user can log in into a database. I swapped the db-access into an external thread. The method startDBCheck()
is called from the listeners when user inputs some text. Here's the code:
public class DBPage
extends MyWizardPage
{
public final class ConnectionCheckingThread
extends Thread
{
boolean interrupted;
@Override
public void run()
{
updateStatus("Checking connection..."); // Method in MyWizardPage using Display.getDefault().asyncExec() to make changes to the GUI
String dbError = Database.getInstance().checkDBAccess(); //checkDBAccess() is synchronized
if (interrupted)
return;
if (dbError != null)
{
updateStatus("Error connecting database: " + dbError);
return;
}
updateStatus(null);
}
public void disable()
{
interrupted = true;
}
}
private ConnectionCheckingThread connectionCheckingThread;
private void startDBCheck()
{
if (connectionCheckingThread != null)
connectionCheckingThread.disable();
connectionCheckingThread = new ConnectionCheckingThread();
connectionCheckingThread.start();
}
}
I am watching the memory usage and notice that the eclipse instance is taking more memory with every change on the graphical interface. If I play with the GUI for some time I get a OutOfMemoryError
. This makes me think the dead threads aren't being deleted by garbage collector for some reason. I don't see any problem in my code though. If i set the reference on connectionCheckingThread to a new thread, there are no other references pointing the old one, so it should be removed. Am I right and the memory leak is somewhere else, or is there really a problem with this part of code?
upd: I get a PermGen space
error which makes me consider if this code look suspicious.
private synchronized Connection getConnection()
throws Exception
{
// load JDBC drivers from jar file
File driverFile = new File(pathToJar);
URL[] urls = {driverFile.toURI().toURL()};
URLClassLoader child = new URLClassLoader(urls, this.getClass().getClassLoader());
Class< ? > clazz = Class.forName(className, true, child);
if (clazz != null)
{
Driver driver = (Driver)clazz.newInstance();
delegatingDriver.setDriver(driver);
DriverManager.registerDriver(delegatingDriver);
}
// Open a connection. If no exception is thrown, the settings work
return DriverManager.getConnection(dbURL, dbUser, dbPassword);
}
upd2: classloading is definitely the cause. Now I need to find out how to fix it.