Performance Swing

12 respostas
tonyam

Olá para todos!

Eu tenho uma aplicação swing acessando Sql Server, uso DAOFactory para manipular as tabelas do banco de dados. A applicação e usada por aproximadamente umas 15 pessoas ao mesmo tempo, na sua maioria em tela onde tem um JTable com renderer, colocando algumas cores diferentes nas linha de acordo com um determinando campo. Também tem um Timer que atualza esse registros em 10 e 10 segundos, porque, todas as máquina tem que ter a mesma visão desses registros, que podem ser alterados por qualquer usuário, e também pode ser mudado de posição.

Problema: A aplicação começa usando 18mb de mémoria e baixo uso de cpu, até aí tudo bem com o passar do tempo o uso de memória vai aumentando e o uso de cpu também, mais ou menos com umas 4(quatro) horas de uso, a memória esta com mais de 100mb e os picos de uso de cpu chega a 100%, justamente na hora em que o JTable esta sendo atualizado.

Não existe loops infinitos e nem Threads, sempre coloco null nos objetos que não estou usando, e memória não baixa de jeito nenhum, mesmo eu fechando essa tela onde tem o Timer.

Vcs podem me ajudar??? como configurar o JVM para otimizar isso.
Sobre profiler, onde encontro, como uso, o que posso fazer.

Estou preocupado com isso, pq uso Eclipse como ide e no eclipse também acontece isso. É normal em aplicações Swing??? Tenho outras aplicações JSP TOMCAT e o servidor funciona uma beleza…

Socorro!!!

12 Respostas

ateubh

cara… voce deve estar fazendo alguma coisa errada nas atualizações dos componentes… poste o código aqui

brlima

ë coisa da aplicaçao muito provavel…
já fiz algumas aplicações com JTable que tem mtos registros, com renderer, etc… Que fica dias aberta… e o pico sempre no mesmo…

Mas antes disso tive problemas com memoria… sempre existe alguma coisa presa nela…

Usei profiler (nao lembro qual) no eclipse que me ajudou a descobrir alguns pontos que afetavam a aplicação…

Dá uma olhada no renderer da cell. Ja tives problemas de memoria com ele…

tonyam

O código é grande, vou posta o método que atualiza o JTable
antes no contructor eu criei o Jtable com dois vector de linhas e colunas

private void atualizaMaterias(){
		

		ArrayList lista = null;
	    SimpleDateFormat df = new SimpleDateFormat("dd/MM/yyyy");
	    SimpleDateFormat tf = new SimpleDateFormat("HH:mm:ss"); 
		JTable jt = getFormMovimento().getJTable();
	    
		lista = Conexao.MOVIMENTODAO.SelectMovimentoTOPagina(getFormMovimento().getJTextField().getText(), getPasta(), getFormMovimento().getJDateChooser().getDate() );

		if (lista==null){
	    	return;
	    }
	    
	    DefaultTableModel model = (DefaultTableModel) jt.getModel();

	    int ii = 0;
	    while ( ii < model.getRowCount()) {
	    	model.removeRow(ii);
		}
	    
	    for (int j = 0; j < lista.size(); j++) {
	
	    	Movimento mv = (Movimento) lista.get(j);
	    	model.insertRow(j,new Object[] {""});
	    	
	    	for (int i = 0; i < ((DefaultTableModel) jt.getModel()).getColumnCount(); i++) {
	    		String coluna = ((DefaultTableModel) jt.getModel()).getColumnName(i);

	    		if (coluna.equals("...")){
	    			jt.setValueAt(mv.getOrdemovimento() ,j , i );
	    		}
	    		
	    		if (coluna.equals("Seq")){
	    			jt.setValueAt(mv.getSequencia() ,j , i );
	    		}
	    		
	    		if (coluna.equals("Página")){
	    			jt.setValueAt(mv.getTipo().equals("BREAK") ? "" :  mv.getPagina() ,j , i );
	    		}	
	    		
	    		if (coluna.equals("Tipo")){
	    			jt.setValueAt(mv.getTipo() ,j , i );
	    		}
	    		
	    		if (coluna.equals("Retranca")){
	    			jt.setValueAt(mv.getRetranca() ,j , i );
	    		}	
	    		if (coluna.equals("Âncora")){
	    			jt.setValueAt(mv.getTipo().equals("BREAK") ? "" : mv.getAncora().getDescricao() ,j , i );
	    		}	
	    		if (coluna.equals("Tempo_Cab")){
	    			jt.setValueAt((  mv.getTempo_Cab() == null ? mv.getTempo_Cab() : tf.format(mv.getTempo_Cab()) ) ,j , i );
	    		}	
	    		if (coluna.equals("Tempo_VT")){
	    			jt.setValueAt((  mv.getTempovt() == null ? mv.getTempovt() : tf.format(mv.getTempovt()) ) ,j , i );
	    		}	
	    		if (coluna.equals("Duração")){
	    			jt.setValueAt((  mv.getDuracao() == null ? mv.getDuracao() : tf.format(mv.getDuracao()) ) ,j , i );
	    		}	
	    		if (coluna.equals("Nº Fita")){
	    			jt.setValueAt(mv.getTipo().equals("BREAK") ? "" : mv.getNumeroFita() ,j , i );
	    		}	
	    		if (coluna.equals("Editor")){
	    			jt.setValueAt(mv.getTipo().equals("BREAK") ? "" : mv.getEditor().getDescricao() ,j , i );
	    		}	
	    		if (coluna.equals("Usuário")){
	    			jt.setValueAt(mv.getUsuario() ,j , i );
	    		}	
	    		if (coluna.equals("Aprovador")){
	    			jt.setValueAt(mv.getAprovador() ,j , i );
	    		}	
	    		if (coluna.equals("Reporter")){
	    			jt.setValueAt(mv.getTipo().equals("BREAK") ? "" : mv.getReporter().getDescricao() ,j , i );
	    		}	
	    		if (coluna.equals("Pasta")){
	    			jt.setValueAt(mv.getPasta().getDescricao() ,j , i );
	    		}	
	    		if (coluna.equals("Data Inclusão")){
	    			jt.setValueAt((  mv.getDataInclusao() == null ? mv.getDataInclusao() : df.format(mv.getDataInclusao()) ) ,j , i );
	    		}	
	    		if (coluna.equals("Data")){
	    			jt.setValueAt((  mv.getData() == null ? mv.getData() : df.format(mv.getData()) ) ,j , i );
	    		}	
	    		if (coluna.equals("Data Alteração")){
	    			jt.setValueAt((  mv.getDataAlteracao() == null ? mv.getDataAlteracao() : df.format(mv.getDataAlteracao()) ) ,j , i );
	    		}	
	    		if (coluna.equals("Status")){
	    			jt.setValueAt(mv.getStatus() ,j , i );
	    		}	
	    		if (coluna.equals("Texto")){
	    			jt.setValueAt(mv.getTexto() ,j , i );
	    		}	
	    		if (coluna.equals("Informações")){
	    			jt.setValueAt(mv.getInformacoes() ,j , i );
	    		}	
	    		if (coluna.equals("hora")){
	    			jt.setValueAt((  mv.getHora() == null ? mv.getHora() : tf.format(mv.getHora()) ) ,j , i );
	    		}	
	    		if (coluna.equals("Pauteiro")){
	    			jt.setValueAt(mv.getTipo() ,j , i );
	    		}	
	    		if (coluna.equals("Jornal")){
	    			jt.setValueAt(mv.getJornal() ,j , i );
	    		}	
	    		if (coluna.equals("Observação")){
	    			jt.setValueAt(mv.getObservacao() ,j , i );
	    		}	
	    		if (coluna.equals("Cinegrafista")){
	    			jt.setValueAt(mv.getCinegrafista().getDescricao() ,j , i );
	    		}	
	    	}
		}

	    lista = null;
	    df = null;
	    tf = null;
		
	}
bueno

você já usou System.gc() ?

quando acaba a memória ram ele passa a usar a hd para armazenar informações e algumas vezes o custo disso pode fazer o processamento ir a 100%

tente usar o System.gc() a cada 1hs depois da atualização da JTable, ele com certeza vai resolver o seu problema de uso de memória

tonyam

bueno:
você já usou System.gc() ?

quando acaba a memória ram ele passa a usar a hd para armazenar informações e algumas vezes o custo disso pode fazer o processamento ir a 100%

tente usar o System.gc() a cada 1hs depois da atualização da JTable, ele com certeza vai resolver o seu problema de uso de memória

vou fazer esse teste…

cassio
tonyam:
...
	    		if (coluna.equals("Seq")){
	    			jt.setValueAt(mv.getSequencia() ,j , i );
	    		}
	    		
	    		if (coluna.equals("Página")){
	    			jt.setValueAt(mv.getTipo().equals("BREAK") ? "" :  mv.getPagina() ,j , i );
	    		}	
	    		
	    		if (coluna.equals("Tipo")){
	    			jt.setValueAt(mv.getTipo() ,j , i );
	    		}
	    		
	    		if (coluna.equals("Retranca")){
	    			jt.setValueAt(mv.getRetranca() ,j , i );
	    		}	
	    		if (coluna.equals("Âncora")){
	    			jt.setValueAt(mv.getTipo().equals("BREAK") ? "" : mv.getAncora().getDescricao() ,j , i );
	    		}	
	    		if (coluna.equals("Tempo_Cab")){
	    			jt.setValueAt((  mv.getTempo_Cab() == null ? mv.getTempo_Cab() : tf.format(mv.getTempo_Cab()) ) ,j , i );
	    		}	
	    		if (coluna.equals("Tempo_VT")){
	    			jt.setValueAt((  mv.getTempovt() == null ? mv.getTempovt() : tf.format(mv.getTempovt()) ) ,j , i );
	    		}	
	    		if (coluna.equals("Duração")){
	    			jt.setValueAt((  mv.getDuracao() == null ? mv.getDuracao() : tf.format(mv.getDuracao()) ) ,j , i );
	    		}	
	    		if (coluna.equals("Nº Fita")){
	    			jt.setValueAt(mv.getTipo().equals("BREAK") ? "" : mv.getNumeroFita() ,j , i );
	    		}	
	    		if (coluna.equals("Editor")){
	    			jt.setValueAt(mv.getTipo().equals("BREAK") ? "" : mv.getEditor().getDescricao() ,j , i );
	    		}	
	    		if (coluna.equals("Usuário")){
	    			jt.setValueAt(mv.getUsuario() ,j , i );
	    		}	
	    		if (coluna.equals("Aprovador")){
	    			jt.setValueAt(mv.getAprovador() ,j , i );
	    		}	
	    		if (coluna.equals("Reporter")){
	    			jt.setValueAt(mv.getTipo().equals("BREAK") ? "" : mv.getReporter().getDescricao() ,j , i );
	    		}	
	    		if (coluna.equals("Pasta")){
	    			jt.setValueAt(mv.getPasta().getDescricao() ,j , i );
	    		}	
	    		if (coluna.equals("Data Inclusão")){
	    			jt.setValueAt((  mv.getDataInclusao() == null ? mv.getDataInclusao() : df.format(mv.getDataInclusao()) ) ,j , i );
	    		}	
	    		if (coluna.equals("Data")){
	    			jt.setValueAt((  mv.getData() == null ? mv.getData() : df.format(mv.getData()) ) ,j , i );
	    		}	
	    		if (coluna.equals("Data Alteração")){
	    			jt.setValueAt((  mv.getDataAlteracao() == null ? mv.getDataAlteracao() : df.format(mv.getDataAlteracao()) ) ,j , i );
	    		}	
	    		if (coluna.equals("Status")){
	    			jt.setValueAt(mv.getStatus() ,j , i );
	    		}	
	    		if (coluna.equals("Texto")){
	    			jt.setValueAt(mv.getTexto() ,j , i );
	    		}	
	    		if (coluna.equals("Informações")){
	    			jt.setValueAt(mv.getInformacoes() ,j , i );
	    		}	
	    		if (coluna.equals("hora")){
	    			jt.setValueAt((  mv.getHora() == null ? mv.getHora() : tf.format(mv.getHora()) ) ,j , i );
	    		}	
	    		if (coluna.equals("Pauteiro")){
	    			jt.setValueAt(mv.getTipo() ,j , i );
	    		}	
	    		if (coluna.equals("Jornal")){
	    			jt.setValueAt(mv.getJornal() ,j , i );
	    		}	
	    		if (coluna.equals("Observação")){
	    			jt.setValueAt(mv.getObservacao() ,j , i );
	    		}	
	    		if (coluna.equals("Cinegrafista")){
	    			jt.setValueAt(mv.getCinegrafista().getDescricao() ,j , i );
	    		}
                        ...

amigo, não dava pra colocar um switch ai não? Fica muito mais rápido que este monte de if... If faz com que seu pipeline vá pro espaço e no seu caso, pior ainda, ele está verificando TODOS estes if's, um por um... Não vi o código todo, mas isso me parece desnecessário...

tonyam

switch para String??? pode??? há posso usar enum…

eu tenho que comparar todas colunas com seus nome, pq dependendo da configuração as colunas não são fixas e iguais para todos os usuários…

vou testar… valeu

cassio

malz, não me atentei ao fato de que eram strings :oops:

Mas deve haver outra maneira… Tipo de vc criasse um esquema de perfis de usuários separado, que para cada usuário te retornasse um array com os nomes das colunas…

cassio

tonyam:
switch para String??? pode??? há posso usar enum…

eu tenho que comparar todas colunas com seus nome, pq dependendo da configuração as colunas não são fixas e iguais para todos os usuários…

vou testar… valeu

Se dá pra usar Enum, não daria pra usar map? Acho que ficaria melhor… Nào sei se entendi direito o problema, mas vc poderia passar pro Map uma string com o nome do usuário e ele te retornaria um array com as colunas…

T

Eu tive um problema que era o de criar N JTables. Como eu não posso usar código de terceiros, então fiz o seguinte: (felizmente posso usar Java 5.0):

  • Criei uma “annotation” para definir colunas de uma JTable. Na definição pomos basicamente o formato, o título da coluna, a largura, etc.)
  • Para cada JTable, defini uma classe que define uma linha dessa JTable;
  • Anotei essa classe (vou chamá-la de Row para facilitar).
  • Derivei uma classe a partir de JTable que define um método setup. Esse método setup cria uma JTable cujo TableModel contém um ArrayList de Row, cujo TableColumnModel define as colunas com suas larguras e títulos etc. Esse JTable também define um método que formata cada dado com a formatação dada na classe Row que foi anotada.
cassio

thingol:
Eu tive um problema que era o de criar N JTables. Como eu não posso usar código de terceiros, então fiz o seguinte: (felizmente posso usar Java 5.0):

  • Criei uma “annotation” para definir colunas de uma JTable. Na definição pomos basicamente o formato, o título da coluna, a largura, etc.)
  • Para cada JTable, defini uma classe que define uma linha dessa JTable;
  • Anotei essa classe (vou chamá-la de Row para facilitar).
  • Derivei uma classe a partir de JTable que define um método setup. Esse método setup cria uma JTable cujo TableModel contém um ArrayList de Row, cujo TableColumnModel define as colunas com suas larguras e títulos etc. Esse JTable também define um método que formata cada dado com a formatação dada na classe Row que foi anotada.

Mas nao fica lento ele terque verificar os atributos a cada nova linha da tabela thingol? Não sei se entendi direito…

tonyam

Finalmente!!!

Depois de muita luta o problema de performance foi resolvido.

O problema era na conexão com o banco. O que resolveu foi desconectar o banco a cada uma hora, sei que não ficou elegante mas, só assim que resolveu.

Criado 21 de dezembro de 2006
Ultima resposta 23 de fev. de 2007
Respostas 12
Participantes 6