Memory Leak in a multi threaded java application (ImageIcon)

C

cakmak

When I profile my swing application with netbeans 5.5 , I notice that
after each periodically tidy up my image container (add,remove
IconImage objects to a hashmap or arraylist), there gather by and by
surviving objects. This leads to run out of memory after a while. Is
there any other way to avoid this effect? Any ideas about "The JVM is
notorious for caching images." I stripped-down my code, this also
gathers surviving objects. An application containing this code could
not live long.



public class LeakCheck {
private int counter=0;
private final String randomquery = "SELECT TOP 4 T00801PersonNr AS
PersonNr,T00801PersonID AS PersonID, T00801Nachname AS
Nachname,T00801Vorname AS Vorname FROM DBA.T00801Person ORDER BY
RAND()";

private class Person extends Object {
private javax.swing.ImageIcon icon;
private String number;
protected void finalize() throws Throwable {
if(icon!=null){
icon.getImage().flush();
icon = null;
}
super.finalize();
}
}
private ArrayList<Person> personList = new ArrayList<Person>();

protected class RefreshTask extends TimerTask {
@Override
public void run() {
random();
}
}
public void go(){
Timer updateTimer = new Timer("Refresh Task");
updateTimer.schedule(new RefreshTask(),0,2000);
}
private Image LoadImageFromDB(String personnr){
Image img = null;
String filename = personnr + ".jpg";
Connection con = getEtrainerDBConnection();
Statement stmt;
ResultSet rs;
try {
stmt = con.createStatement();
String query = Resources.getProperty("selectPersonImage");
query = String.format(query, filename);
rs=stmt.executeQuery(query);
if(rs.next()){
int len=rs.getInt(2);
byte [] b=new byte[len];
InputStream in = rs.getBinaryStream(3);
try {
in.read(b);
in.close();
img=Toolkit.getDefaultToolkit().createImage(b);
} catch (IOException e) {
e.printStackTrace();
}
}
rs.close();
stmt.close();

} catch (SQLException e) {
e.printStackTrace();
}
return img;
}
public void random(){
java.sql.Connection con = getSybaseDBConnection();
try {
if(con!=null && !con.isClosed()){
java.sql.Statement stmt=null;
try {
stmt = con.createStatement();
java.sql.ResultSet rs =
stmt.executeQuery(randomquery);
while(rs.next()){
Person person = new Person();
person.number = rs.getString("PersonNr");
Image img = LoadImageFromDB(person.number);
if(img !=null){
ImageIcon ico = new ImageIcon(img);
person.icon = ico;
}
personList.add(person);
System.out.println("Container size: " +
personList.size());
counter++;
}
if(counter%20 == 0){
personList.clear();
System.gc();//no need, but I force
System.out.println("size: " +
personList.size());
}
rs.close();
stmt.close();
} catch (SQLException ex) {
ex.printStackTrace();
}
}
} catch (SQLException ex) {
ex.printStackTrace();
}
}
public static void main(String[] args) {
LeakCheck leakCheck = new LeakCheck();
leakCheck.go();
}
}
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,821
Messages
2,569,748
Members
45,726
Latest member
RaleighAll

Latest Threads

Top