Usuário com melhor resposta
Problemas com memória

Pergunta
-
Tenho problemas de um consumo de memória cumulativo e progressivo em sistemas desenvolvidos em .NET.
Por exemplo, eu testei 2 maneiras diferentes:
Usando os objetos como Shared para todas as classes de regras de negócios, parece acumular mais memória.
Instanciando e setando para nothing os objetos necessários em cada método, acumula memória tbm, mas de uma maneira menos intensa.
Há alguma maneira mais aconselhável (ou ideal) de se usar os objetos? (Notadamente os Datatables, DataReaders, Parameters, Command, Connection e Adapter)
O Garbage Collector não deveria cuidar desse problema todo?
Respostas
-
Felipe,
você está fechando todas as conexões?
Veja algumas discussões sobre chamar ou não explicitamente o Garbage Collector:
C# Tip: Forcing Garbage Collection in .NET - http://www.developer.com/net/csharp/article.php/3343191
.NET GC Best Practice -- ALWAYS Call Dispose - http://weblogs.asp.net/pwilson/archive/2004/02/20/77435.aspx
Dispose and close or close without dispose - http://weblogs.asp.net/pleloup/archive/2004/02/03/66623.aspx
ADO.NET Database connections - Close() Vs. Dispose() - http://codebetter.com/blogs/sahil.malik/archive/2004/12/31/40036.aspx- Sugerido como Resposta AndreAlvesLimaModerator sexta-feira, 23 de julho de 2010 21:56
- Marcado como Resposta AndreAlvesLimaModerator sexta-feira, 30 de julho de 2010 21:48
-
Felipe,
Quando você seta uma variável para Nothing (null no C#), você não faz com que a classe libere os recurso alocados por ela, você só mata a instancia dela, mas os recursos continuam alocados por ela.
Acho que em VB.Net também existe a diretiva using. Ela chama o método dispose, caso a classe implemente a interface IDisposable, após um bloco de execução. Um exemplo simples:
using ( SqlConnection cn = new SqlConnection(connectionString) )
{
cn.Open();
using ( SqlCommand cmd = new SqlCommand() )
{
cmd.CommandText = "";
cmd.CommandType = "";
cmd.ExecuteNonQuery();
}
}
Desculpa se o exemplo é em C#, é que eu to mais acostumado com a linguagem. :)
Bom espero que ajude.
[]´s
Thiago Oliveira- Sugerido como Resposta AndreAlvesLimaModerator sexta-feira, 23 de julho de 2010 21:56
- Marcado como Resposta AndreAlvesLimaModerator sexta-feira, 30 de julho de 2010 21:48
-
Felipe,
O Garbage Collector cuida disso desde que você solicite que ele o faça.
objetoconnection.Dispose () ;
Faz com que o objeto seja colocado à disposição da coleta de lixo.
Você pode pensar em configurar o seu servidor com pool de conexões.
Não conheço a arquitetura do seu sistema, mas onde você diz que usou objetos shared, o ideal não seria Static ? Pq o Static é instanciado só uma vez, vc não usa o new.
- Sugerido como Resposta AndreAlvesLimaModerator sexta-feira, 23 de julho de 2010 21:56
- Marcado como Resposta AndreAlvesLimaModerator sexta-feira, 30 de julho de 2010 21:48
Todas as Respostas
-
Felipe,
você está fechando todas as conexões?
Veja algumas discussões sobre chamar ou não explicitamente o Garbage Collector:
C# Tip: Forcing Garbage Collection in .NET - http://www.developer.com/net/csharp/article.php/3343191
.NET GC Best Practice -- ALWAYS Call Dispose - http://weblogs.asp.net/pwilson/archive/2004/02/20/77435.aspx
Dispose and close or close without dispose - http://weblogs.asp.net/pleloup/archive/2004/02/03/66623.aspx
ADO.NET Database connections - Close() Vs. Dispose() - http://codebetter.com/blogs/sahil.malik/archive/2004/12/31/40036.aspx- Sugerido como Resposta AndreAlvesLimaModerator sexta-feira, 23 de julho de 2010 21:56
- Marcado como Resposta AndreAlvesLimaModerator sexta-feira, 30 de julho de 2010 21:48
-
Ricardo,
Passar o connection para Nothing (cnn = nothing) não teria a mesma funcionalidade de cnn.close?
Na verdade, eu dei uma olhada no código, e eu dou o Close, e ainda dou o =nothing.
Em datareaders tbm faço a mesma coisa.
Eu isolei tudo referente a acesso a dados em uma camada da aplicação, estou te enviando um exemplo de Função que usa manipulação de dados. Pode me sugerir alguma otimização?
Public Overloads Function ExecutarSQLScalar(ByVal vSQL As String, ByVal vParametro As IDbDataParameter, Optional ByVal vCommandType As CommandType = CommandType.Text) As Object
mParams.PrepararParametros(vParametro, mDBINI.CMD)
mInnerCall = True
Return ExecutarSQLScalar(vSQL, vCommandType) End Function
CNX.Close()
CNX = Nothing
CMD = Nothing
DA = Nothing End Sub Public Overloads Function ExecutarSQLScalar(ByVal vSQL As String, ByVal vParametros As IDbDataParameter(), Optional ByVal vCommandType As CommandType = CommandType.Text) As Object mParams.PrepararParametros(vParametros, mDBINI.CMD)
mInnerCall = True
Return ExecutarSQLScalar(vSQL, vCommandType) End Function Public Overloads Function ExecutarSQLScalar(ByVal vSQL As String, Optional ByVal vCommandType As CommandType = CommandType.Text) As Object Try If mInnerCall = False Then mParams.LimparParametros(mDBINI.CMD)
If Transacao = False Then mDBINI.CNX.Open()
mDBINI.CMD.CommandType = vCommandType
mDBINI.CMD.CommandText = vSQL
ExecutarSQLScalar = mDBINI.CMD.ExecuteScalar()
Catch ex As Exception
Throw New DBLibException("ExecutarSQLScalar: " & ex.Message, ex)
ExecutarSQLScalar = Nothing
Finally If Transacao = False Then mDBINI.CNX.Close()
mInnerCall = False
End Try End FunctionProtected Overrides Sub Finalize()
Private Sub LimparDBLib()
LimparDBLib()
End Sub
CNX = Nothing ' Connection
CMD = Nothing 'Command
DA = Nothing 'Adapter
End Sub -
Felipe,
Quando você seta uma variável para Nothing (null no C#), você não faz com que a classe libere os recurso alocados por ela, você só mata a instancia dela, mas os recursos continuam alocados por ela.
Acho que em VB.Net também existe a diretiva using. Ela chama o método dispose, caso a classe implemente a interface IDisposable, após um bloco de execução. Um exemplo simples:
using ( SqlConnection cn = new SqlConnection(connectionString) )
{
cn.Open();
using ( SqlCommand cmd = new SqlCommand() )
{
cmd.CommandText = "";
cmd.CommandType = "";
cmd.ExecuteNonQuery();
}
}
Desculpa se o exemplo é em C#, é que eu to mais acostumado com a linguagem. :)
Bom espero que ajude.
[]´s
Thiago Oliveira- Sugerido como Resposta AndreAlvesLimaModerator sexta-feira, 23 de julho de 2010 21:56
- Marcado como Resposta AndreAlvesLimaModerator sexta-feira, 30 de julho de 2010 21:48
-
Felipe,
O Garbage Collector cuida disso desde que você solicite que ele o faça.
objetoconnection.Dispose () ;
Faz com que o objeto seja colocado à disposição da coleta de lixo.
Você pode pensar em configurar o seu servidor com pool de conexões.
Não conheço a arquitetura do seu sistema, mas onde você diz que usou objetos shared, o ideal não seria Static ? Pq o Static é instanciado só uma vez, vc não usa o new.
- Sugerido como Resposta AndreAlvesLimaModerator sexta-feira, 23 de julho de 2010 21:56
- Marcado como Resposta AndreAlvesLimaModerator sexta-feira, 30 de julho de 2010 21:48