181 messaggi dal 23 marzo 2006
salve a tutti,
ho scritto un servizio Windows, in C#.
Il servizio, funziona da "client" pop3 in background.

Ho un timer, che ogni 30 secondi accede ad una serire di caselle pop3, e scorre tutti i messaggi presenti. Alcuni di essi vengono salvati su disco e vengono inserite delle righe su un DB Sql.

Tutto funziona correttamente... l'unico problema è che la dimensione in memoria occupata dal servizio, cresce, e non di poco.
Partendo da una base di 15mb, nel giro di 48 ore, arrivo a 280mb... e dopo due settimane, beh... out of memory.

Ho provato a documentarmi sull'argomento...
Ho provveduto a:
- Chiamare il "GC.Collect()" dopo aver "analizzato" ogni casella POP3.
- Chiamare i metodi "Dispose()" di tutti gli oggetti "disposable" (tutti... almeno spero)
- Eliminare tutti gli oggetti "Statici" (globali)

Qualcuno sa darmi un consiglio?

Grazie.
Purtroppo c'è poco altro da suggerirti se non di controllare che non fai crescere collezioni o array all'infinito e che non chiami il dispose (anche in caso di errore) di tutti gli oggetti che implementano IDisposable. Purtroppo è difficile fare una refisione a posteriori.
Chiamare GC.Collect non serve, ti assicuro che gli oggetti che si possono eliminare gli cancella già solo. Il processo di garbage parte anche più volte al secondo.

Ciao

Il mio blog
Homepage
181 messaggi dal 23 marzo 2006
si, la cosa del GC la sapevo... lo chiamo soltanto per avere una diagnostica "realtime" del problema.


ok, vediamo se magari mi sono perso qualche "disposabile"...


io chiamo il dispose di:
DataView
DbTransaction
MailMessage

Altri oggetti standard che posso essermi "perso"? Tipo, le List<> vanno ripulite?
Ha qualche senso mettere a null le istanze prima di perdere lo Scope?
181 messaggi dal 23 marzo 2006
Ah, le DbConnection le utilizzo sempre dentro un blocco

Using(DbConnection myConn = ....)
{
....
}

devo comunque chiamare la dispose?
Naa, non serve mettere a null. Se sono a livello di stack si perdono da sole. Controlla tutti gli Stream, Socket, tutto ciò che eredita da Component

Ciao

Il mio blog
Homepage
181 messaggi dal 23 marzo 2006
salve a tutti,
sono riuscito ad isolare il problema....

questo metodo, viene chiamato ogni 100 ms, e consuma all'incirca 2kb/s.

Ho provato a fare la profilatura del servizio con il ".Net Memory Profiler". Se mi spiegate come fare magari vi posto il grafico...

Il metodo incriminato è questo:
(commentando la parte "myCommand.ExecuteReader()", tutto torna ok...)



private void Aggiorna()
{
using (DbConnection myConn = new OleDbConnection())
{

string aQuery = "SELECT * FROM Tabella ";

DbCommand myCommand = new OleDbCommand();
myCommand.Connection = myConn;
myCommand.CommandText = aQuery;
myCommand.CommandTimeout = 300;

using (OleDbDataReader myDataView = (OleDbDataReader)myCommand.ExecuteReader())
{
//non fa niente....
}

myCommand.Dispose();

}
}



dove sta l'inghippo?

mi sa che oggi non siamo tanti a lavorare... ma se non sistemo questa cosa, beh... non è bello.


EDIT: il consumo di memoria, secondo il memory profiler, è causato da risorse di tipo "unmanaged"
Modificato da liscio il 14 agosto 2008 10.53 -
Beh il fatto che consumi non vuol dire che sprechi. Fai correttamente la dispose. Metti in using anche il command, tanto per essere sicuri, invece di chiamare te la dispose.
Ma non vedo niente che generi memory leak. Se non te ne fai niente del reader perché non chiama ExecuteNonQuery?

Ciao

Il mio blog
Homepage
181 messaggi dal 23 marzo 2006
no, vabbeh, questo metodo è fatto a scopo di test... ho sbudellato tutta l'applicazione...

In pratica ora il mio WindowsService non fa proprio un bel tubo di niente. Fa solo quella select (sono 3 righe nella tabella), ogni 100ms.

Il problema è che, con questo trend, in una settimana mi va "OutOfMemory", e mi pianta il server e io faccio una brutta fine...

I test li ho fatti con questa applicazione creata apposta. Con la versione "vera", il System.OutOfMemory lo raggiungi anche con intervalli di 10 minuti (invece che 100 millisecondi).

Può dipendere dal fatto che uso gli "OleDB" ?

Il server è un SQL Server 2005.

Torna al forum | Feed RSS

ASPItalia.com non è responsabile per il contenuto dei messaggi presenti su questo servizio, non avendo nessun controllo sui messaggi postati nei propri forum, che rappresentano l'espressione del pensiero degli autori.