Não libera componentes da memória

Ae pessoal, estou tendo um problema meio estranho aqui…

Ao executar o codigo abaixo o Garbage Collector não consegue liberar os componentes criados com o JDialog, ou seja, há um consumo crescente de memória. Já tentei usar a instrução dispose da JDialog ao finalizar a classe e também chamar o GC explicitamente, mas também não adiantou. Usei a instrução finalize tbm para verificar se os objetos DialogMessage e a Thread interna foram excluídos pelo GC, e de fato foram, mas os objetos criados JDialog, JLabel, GridBagLayout e os containers do JDialog como o JPanel, JRootPane, etc… não foram excluídos, eles ficam na memória.

Para fazer esta análise usei o JProbe.

import java.awt.*;
import javax.swing.*;
import javax.swing.border.LineBorder;

class DialogMessage {
   private JDialog dialog;
   private String text="";
   private int milliseconds;

   class InternalThread extends Thread {
      @Override
      public void run() {
         try { Thread.sleep(milliseconds);
         } catch (InterruptedException e) { e.printStackTrace(); }
         dialog.setVisible(false);
      }
   };

   public DialogMessage(JFrame frameOwner, String text, int milliseconds) {
      this.dialog = new JDialog(frameOwner);
      this.text = text;
      this.milliseconds = milliseconds;

      dialog.setSize(600, 200);
      Container dc =  dialog.getContentPane();
      dc.setLayout(new GridBagLayout());
      GridBagConstraints gbc = new GridBagConstraints();
      gbc.weightx=gbc.weighty=1; gbc.fill=GridBagConstraints.BOTH;
      JLabel lbText = new JLabel(text);
      lbText.setHorizontalAlignment(JLabel.CENTER);
      lbText.setFont(new Font("Arial",Font.BOLD,24));
      lbText.setBorder(new LineBorder(Color.gray));
      dc.add(lbText,gbc);
      dialog.setModal(true);
      dialog.setUndecorated(true);
      dialog.setLocationRelativeTo(frameOwner);
   }

   public void setVisible(boolean visible) {
      InternalThread it = new InternalThread();
      if (visible)  it.start();      
      dialog.setVisible(visible);
      it=null;
   }

}

public class FormMemory extends JFrame {
   public static void showMessageDelayed(JFrame frameOwner, String text, int milliseconds) {
      DialogMessage d =  new DialogMessage(frameOwner,text,milliseconds);
      d.setVisible(true);
   }

   public FormMemory() {
      this.setSize(400,400);
      this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

      new Thread() {
         public void run() {
            while (true) {
               showMessageDelayed(FormMemory.this, "Testando aplicacao", 100);
               try { Thread.sleep(10);
               } catch (InterruptedException e) { e.printStackTrace(); }
            }      
         };
      }.start();      

      this.setVisible(true);

   }

   public static void main(String Args[]) { new FormMemory(); }
}

Enviei pra um amigo meu, e a msm situação ocorre.
Deve haver algum tipo de referência obscura ao JDialog, ou talvez seja um BUG do GC?! icchh

se alguém souber algo a respeito, comenta ai, agradeço…

Enviei um arquivo de texto anexado referente a memória desse programinha em execução, e a quantidade de objetos referenciados e tbm seu gráfico de execução na memória.


aeww, consegui acertar o código, realmente quando eu testei com dialog.dispose() ele não funcionava, talvez porque usei ele em um finalizador da classe DialogMessage, mas agora ele parece esta funcionando bem

import java.awt.*;
import javax.swing.*;
import javax.swing.border.LineBorder;

class DialogMessage {

	private JDialog dialog;
	private String text="";
	private int milliseconds;
	
	Thread iThread = new Thread() {
		@Override
		public void run() {
			try { Thread.sleep(milliseconds);
			} catch (InterruptedException e) { e.printStackTrace(); }
			dialog.setVisible(false);
		}
	};
	
	public DialogMessage(JFrame frameOwner, String text, int milliseconds) {
		this.dialog = new JDialog(frameOwner);
		this.text = text;
		this.milliseconds = milliseconds;
	
		dialog.setSize(600, 200);
		Container dc =  dialog.getContentPane();
		JLabel lbText = new JLabel(text);
		lbText.setHorizontalAlignment(JLabel.CENTER);
		lbText.setFont(new Font("Arial",Font.BOLD,24));
		lbText.setBorder(new LineBorder(Color.gray));
		dc.add(lbText);
		dialog.setModal(true);
		dialog.setUndecorated(true);
		dialog.setLocationRelativeTo(frameOwner);
		iThread.start();
		dialog.setVisible(true);
		dialog.dispose();
	}
}

public class FormMemory	extends JFrame {
	
	public static void showMessageDelayed(JFrame frameOwner, String text, int milliseconds) {
		new DialogMessage(frameOwner,text,milliseconds);
	}
	
	public FormMemory() {
		this.setSize(400,400);
		this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		
		new Thread() {
			public void run() {
				while (true) {
					showMessageDelayed(null, "Testando aplicacao", 100);
					System.gc();
					try { Thread.sleep(10);
					} catch (InterruptedException e) { e.printStackTrace(); }
				}			
			};
		}.start();		
		
		this.setVisible(true);
	}
	
	public static void main(String Args[]) { new FormMemory(); }
}