Ae pessoal, postei um problema agora a pouco sobre o acúmulo de memória por JDialog e seu subcomponentes, e pensando nisso, resolvi fazer mais alguns testes na aplicação, e olha que interessante, há algumas restrições ao desenvolver aplicações que não são citados na maioria dos tutoriais e documentações sobre java…
Como é ensinado, programador java não precisa se preocupar com a memória… verdade? bom, aqui não vejo isso… apesar de não existir os famosos free e delete do c++, o java ainda prega algumas peças.
vou citar o teste que eu fiz…
deem uma olhada no código abaixo
public static void main(String Args[]) {
new Thread() {
@Override
public void run() {
try {
while (true) {
100");
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery("Select * from Fisica Limit 100");
System.gc();
Thread.sleep(100);
rs.close();
stmt.close();
}
} catch (Exception e) { e.printStackTrace(); }
}
}.start();
}
bom, explicando o código:
conn é o objeto de conexao java (java.sql.Connection)
Traz 100 registros de uma tabela mysql
Chama o GC para ter certeza que ele limpe os objetos ñ referenciados
Para o processamento por 100 milisegundos
Fecha o ResultSet e o Statement
bom, se rodarmos esse código, vai executar com perfeição, e analisando a memória, não econtraremos problemas…
Os testes com o JProbe mostram o seguinte:
a cada execução do loop, ná memória consta
Statement = 1 instancia
ResultSet = 1 instancia
bom, até ai tudo bem, mas vamos alterar nosso código para ficar mais cômodo… coisa que muitos programadores fazem
a alteração abaixo é simples, mas há programadores que fazem classes pra gerenciar selects, inserts, etc… comunicações com o banco em geral
public static ResultSet select(String campos, String tabela, String opts) {
try {
Statement stmt = Sys.conn.conn.createStatement();
return stmt.executeQuery("Select " + campos + " from " + tabela + " " + opts);
} catch (Exception e) { e.printStackTrace(); }
return null;
}
public static void main(String Args[]) {
new Thread() {
@Override
public void run() {
try {
while (true) {
ResultSet rs = select("*","Fisica","Limit 100");
System.gc();
Thread.sleep(100);
rs.close();
}
} catch (Exception e) { e.printStackTrace(); }
}
}.start();
}
Agora nós temos um método para executar o nosso select…
bom, executando o código, aparentemente está pérfeito, e a memória parece estável primeira vista, mas analisando a memória a fundo, notamos que os objetos
Statement, ResultSet, e seus sub-objetos ainda ficam instanciados, ou seja, a cada execução do loop, o numero de referências a statement, resultset, etc… aumenta mais uma…
Isso não deveria acontecer pois o que fica para o programador é que não há referencia alguma para o Statement criado dentro de
public static ResultSet select(String campos, String tabela, String opts)
mas parece que ele mantém sim uma referência, talvez no proprio resultset de retorno, cujo eu fecho depois e teoricamente perderia referência… vou continuar a fazer mais testes para verificar onde…
elevando este problema para um sistema grande, se ocorrer uma grande quantia de transações pode ocorrer problemas de memórias que dificilmente são encontrados… como ocorreu com um sistema que desenvolvi aqui, no meio de sua execução, dava problema de memória. Isto ocorria após 2 horas de funcionamento, o que torna a depuração complicada…
Bom, por fim, isso nos mostra que as documentações java e tutoriais espalhados pela net, dificilmente informam sobre este tipo de controle, que de fato, é muito importante para nós programadores…
Estes argumentos foram baseados em testes com o JProbe, análise de instâncias em runtime, e consumo detalhado de memória por objeto, etc…
Se alguém tiver algum conhecimento mais específico sobre isso e quiser compartilhar, agradeço…