Uso do finally

Senhores, bom dia.

Estou lendo alguns artigos que falam sobre o outOffMemory e cheguei a um questionamento, é boa pratica sempre que usarmos o try/catch usarmos também o finally para liberar “memoria”, quero dizer fechar conexões abertas e setar null em objetos que não iremos usar mais???

att

Não é só uma boa prática. É uma necessidade. Você deve, obrigatoriamente, usar o finally para fechar conexões, statements, streams, ou qualquer classe que diga que você tem que dar algum comando especial de fechamento. Isso pode não só impactar em OutOfMemory, como também estouro de conexões no banco de dados, arquivos que não podem ser mais alterados porque ainda estão abertos, etc.

Quanto a definir objetos como null, isso só é necessário se a variável daquele objeto ainda se mantiver no escopo. Caso contrário, o java fará isso automaticamente assim que a variável deixar de existir.

Depende da situação. Cada caso é um caso, não podemos considerar isso como uma boa prática e portanto sempre aplicar. É uma boa prática, mas não pode ser usado em todos os lugares, indiscriminadamente. Apenas quando for verificado a necessidade.

Existem algumas pessoas que utilizam no hibernate o bloco, try/catch para abrir a sessão e persistir o objeto e depois usam o finally para fechar a sessão.

[quote=rubensdemelo]Depende da situação. Cada caso é um caso, não podemos considerar isso como uma boa prática e portanto sempre aplicar. É uma boa prática, mas não pode ser usado em todos os lugares, indiscriminadamente. Apenas quando for verificado a necessidade.

Existem algumas pessoas que utilizam no hibernate o bloco, try/catch para abrir a sessão e persistir o objeto e depois usam o finally para fechar a sessão. [/quote]

Ótimo. Cite um único caso onde deixar o recurso aberto é uma boa.

Você pode citar, para permitir a técnica de pooling. Mesmo nessa caso, em algum momento, você terá que garantir o fechamento do pool, e terá que haver finallys para devolver objetos para o pool.

[quote=ViniGodoy][quote=rubensdemelo]Depende da situação. Cada caso é um caso, não podemos considerar isso como uma boa prática e portanto sempre aplicar. É uma boa prática, mas não pode ser usado em todos os lugares, indiscriminadamente. Apenas quando for verificado a necessidade.

Existem algumas pessoas que utilizam no hibernate o bloco, try/catch para abrir a sessão e persistir o objeto e depois usam o finally para fechar a sessão. [/quote]

Ótimo. Cite um único caso onde deixar o recurso aberto é uma boa.

Você pode citar, para permitir a técnica de pooling. Mesmo nessa caso, em algum momento, você terá que garantir o fechamento do pool, e terá que haver finallys para devolver objetos para o pool.[/quote]

Você não entendeu…

Eu disse que em alguns casos o uso do finally é indicado, e citei como exemplo o Hibernate. Porém em outros casos, (sem ser com o hibernate) o uso de finally não é necessário. Ou seja.

No exemplo que citei, o uso do finally é fortemente recomendado. Em alguma outra situação(em qualquer lugar, com qualquer framework), o seu uso pode ser desnecessário.

então essa função do finally(fechar conexões: de banco, stream), isso já faço mas a minha duvida era mais mesmo quando a setar null em objetos, para mostrar para o GC que esses objetos já estão obtos a serem limpados da memoria.

Para compreender porquê isso é inutil /util vc tem que tender a diferença entre variável e objeto.
Lá porque vc faz a sua variável ser null e portanto não apontar mais para o objeto , isso não significa que não exista outra variável apontanto o mesmo objeto. Portanto, colocar null é normalmente inutil. Todo o conceito do GC é saber quem aponta o quê para que vc não tenha que saber. Setar como null pode ser util num caso muito particular , mesmo sem finally. Para saber se está perante esse caso ou não , vc precisa entender o modelo de memoria da jvm e como e quando o CG opera.

O java sempre torna as variáveis null quando elas saem do escopo. Portanto, essa é a forma mais eficiente e lógica de controlar as variáveis : defini-las no escopo certo.

por exemplo, quando vc faz um for assim

for (int i =0 ; i < 5 ; i ++ ){
   // faz algo com i
}

// aqui o i não existe mais

na linha depois do for o i não existe mais. porque ele pertencia apenas ao escopo do for, quando o for acabou o i acabou junto com ele. É por isso que quando se usa iterator se usa for e não while

for (Iterator it =col.iterator() ; it.hasNext();){
   // faz algo com iterator
}

// aqui o it não existe mais
Iterator it =col.iterator()
while(it.hasNext()){
   // faz algo com iterator
}

// aqui o it ainda existe

Repare que a diferença do fluxo é nehuma, mas o segundo codigo mantém o iterador mesmo depois dele ser usado.
Se o método que usa isto é muito longo vc está gastando memória referenciando o iterator à toa.
Vc poderia fazer it=null depois do while, mas a forma mais eficiente seria usar o for porque assim vc não vai esquecer
nem os outros programadores vão esquecer.

Opa, muito obrigado pela explicação, acho que tirou sim a minha duvida…vlw