Ho un requisito insolito per il codice su cui sto lavorando. Sto usando una libreria di terze parti inaffidabile per fare una scansione di codici a barre (smette di funzionare dopo aver eseguito troppe volte). Per ovviare a questo problema, ho deciso di eseguire il lavoro in un AppDomain separato e quindi di scaricare AppDomain al termine. Questa è una foto semplicistico, ma precisa, di quello che sto facendo:Perdita di memoria brutto durante il caricamento del codice in AppDomain
string domainID = Guid.NewGuid().ToString();
AppDomainSetup setup = new AppDomainSetup();
AppDomain domain = AppDomain.CreateDomain(domainID, null, setup);
string result = null;
try
{
domain.SetData("stream", stream);
domain.DoCallBack(ScanningContext.DoWork);
result = domain.GetData("result") as string;
}
finally
{
AppDomain.Unload(domain);
}
return result;
public static void DoWork()
{
Stream s = AppDomain.CurrentDomain.GetData("stream") as Stream;
ObjectHandle handle = AppDomain.CurrentDomain.CreateInstance("Scanning",
"Scanner");
Scanning.Scanner scanner = (Scanning.Scanner)handle.Unwrap();
Scanning.Result[] results = scanner.Scan(s);
AppDomain.CurrentDomain.SetData("result", results[0].Text);
}
"Scanner" è una classe wrapper intorno alla biblioteca che sto utilizzando. Si trova nell'assembly "Scanning"; un progetto separato solo per questo scopo.
ScanningContext.DoWork è un metodo statico che si trova nell'assembly del mio servizio.
Il mio problema con questo metodo è che c'è una perdita di memoria in qualche luogo. La memoria continua a crescere (quando viene chiamato questo codice, ovviamente) fino a quando non vengono lanciate OutOfMemoryExceptions.
Non riesco a trovare la perdita da nessuna parte. Tutti i miei flussi sono disposti. Tutti i miei array di byte vengono annullati. Sto cancellando le liste, tutto ciò che ha funzionato per me in passato. Sono sicuro al 90% circa che la perdita sia correlata a questa roba AppDomain. Questa è la mia prima volta che la uso, quindi probabilmente sto facendo qualcosa di sbagliato.
Sono aperto a un altro approccio oltre a AppDomains. Richiedo la possibilità di restituire risultati dalla classe "Scanner", quindi generare un processo non è un'opzione.
Si dice che è possibile eseguire il codice di terze parti almeno un paio di volte. Quindi, puoi escludere l'ultima incertezza del 10% verificando se la perdita esiste anche senza utilizzare domini app? –
Rimuovere il codice di chiamata dello scanner, restituire un risultato fisso e controllare se la memoria perde ancora lì, quindi il suo problema di AppDomain, altrimenti è il problema della libreria di terze parti. –
Il vecchio metodo consuma molta memoria, circa 250.000k mentre guardo ora, quindi, l'uso della memoria non è buono. Tuttavia non ha esaurito la memoria come sta facendo il mio nuovo approccio. Quindi per rispondere alla tua domanda, no non posso escludere l'altro 10%, ho dovuto riscrivere un po 'di codice per usare AppDomains in modo da poter introdurre la perdita in quel momento. – Matthew