La presentazione è in caricamento. Aspetta per favore

La presentazione è in caricamento. Aspetta per favore

Gestione della memoria e delle risorse in.NET Marco Russo MCSD MCAD MCSE+I MCSA MCDBA MCT Mail: Italian blog:

Presentazioni simili


Presentazione sul tema: "Gestione della memoria e delle risorse in.NET Marco Russo MCSD MCAD MCSE+I MCSA MCDBA MCT Mail: Italian blog:"— Transcript della presentazione:

1 Gestione della memoria e delle risorse in.NET Marco Russo MCSD MCAD MCSE+I MCSA MCDBA MCT Mail: Italian blog:

2 Iscriviti su Gestione e infrastruttura di rete Gestione e infrastruttura di rete Smart Client: la potenza del PC e la connettività Web Smart Client: la potenza del PC e la connettività Web Gestione dell'infrastruttura dei sistemi di produttività aziendale Gestione dell'infrastruttura dei sistemi di produttività aziendale Sicurezza e interoperabilità Sicurezza e interoperabilità Guest Speaker Bill Gates Non perdere l'appuntamento dedicato ai professionisti IT e agli sviluppatori

3 DevLeap: chi siamo Un gruppo di 5 persone con tanta voglia diUn gruppo di 5 persone con tanta voglia di Studiare a fondo le tecnologieStudiare a fondo le tecnologie Capire il behind the scenesCapire il behind the scenes Implementare soluzioni realiImplementare soluzioni reali Confrontarsi con le problematiche realiConfrontarsi con le problematiche reali Sperimentare nuove ideeSperimentare nuove idee Facciamo Corsi, Conferenze, TrainingFacciamo Corsi, Conferenze, Training Scriviamo libriScriviamo libri

4 Chi siete ? Chi usa già.NET?Chi usa già.NET? Chi usa C#?Chi usa C#? Chi usa VB.NET?Chi usa VB.NET? Chi usa C++/Managed C++?Chi usa C++/Managed C++? Chi conosce Java?Chi conosce Java?

5 Agenda Perché il Garbage CollectorPerché il Garbage Collector Algoritmo mark-and-compactAlgoritmo mark-and-compact F-reachable queueF-reachable queue Pattern IDisposablePattern IDisposable ResurrectionResurrection Weak ReferenceWeak Reference Algoritmo generazionaleAlgoritmo generazionale Thread e Garbage CollectorThread e Garbage Collector Garbage Collector vs. Heap Win32Garbage Collector vs. Heap Win32

6 Perché il Garbage Collector La gestione della memoria è fondamentale nei linguaggi a oggettiLa gestione della memoria è fondamentale nei linguaggi a oggetti I modelli tradizionali sono deterministici:I modelli tradizionali sono deterministici: Distruzione manuale (C, C++, Win32)Distruzione manuale (C, C++, Win32) Reference counting (COM, VB)Reference counting (COM, VB) Minore uso di memoriaMinore uso di memoria Maggiore consumo di CPUMaggiore consumo di CPU Modelli alternativi (euristici):Modelli alternativi (euristici): Mark/sweepMark/sweep Copy collectCopy collect Mark/compactMark/compact

7 Algoritmi di Garbage Collection Mark/SweepMark/Sweep Segna tutti gli oggetti raggiungibiliSegna tutti gli oggetti raggiungibili Gli oggetti non raggiungibili vengono distruttiGli oggetti non raggiungibili vengono distrutti Crea frammentazione memoria liberaCrea frammentazione memoria libera Copy CollectCopy Collect Copia tutti gli oggetti raggiungibili in una nuova zona di memoria (contigua)Copia tutti gli oggetti raggiungibili in una nuova zona di memoria (contigua) Aggiorna tutti i riferimenti agli oggetti copiatiAggiorna tutti i riferimenti agli oggetti copiati Libera la zona di memoria esaminataLibera la zona di memoria esaminata Mark/CompactMark/Compact Soluzione ibrida, implementata da.NETSoluzione ibrida, implementata da.NET

8 Algoritmo mark-and-compact Allocazione sequenziale di tutti gli oggettiAllocazione sequenziale di tutti gli oggetti Alte prestazioniAlte prestazioni a.ba2.b a a a2 b A a = new A(); a.b = new B(); A a2 = new A(); a2.b = new B(); NextObjPtr

9 Algoritmo mark-and-compact Loperazione di Garbage Collection raccoglie gli oggetti non raggiungibiliLoperazione di Garbage Collection raccoglie gli oggetti non raggiungibili Avviene automaticamente quando lheap cresceAvviene automaticamente quando lheap cresce Pilotata manualmente da GC.Collect()Pilotata manualmente da GC.Collect() Due fasi:Due fasi: 1.Mark individua la memoria non raggiungibile 2.Compact sposta tutti gli oggetti allinizio dellheap, aggiornando tutti i riferimenti

10 GC fase 1: Mark Identifica gli oggetti referenziati, raggiungibili da posti conosciuti (root set):Identifica gli oggetti referenziati, raggiungibili da posti conosciuti (root set): Proprietà AppDomainProprietà AppDomain Registri CPURegistri CPU Slot TLSSlot TLS Variabili locali sullo stackVariabili locali sullo stack Membri statici delle classiMembri statici delle classi Iterazione ricorsiva degli oggetti referenziati per segnare tutti gli oggetti raggiungibiliIterazione ricorsiva degli oggetti referenziati per segnare tutti gli oggetti raggiungibili

11 GC fase 2: Compact Tutti gli oggetti raggiungibili vengono spostati allinizio dellheapTutti gli oggetti raggiungibili vengono spostati allinizio dellheap Tutti i riferimenti vengono aggiornatiTutti i riferimenti vengono aggiornati Lo spazio libero non resta frammentatoLo spazio libero non resta frammentato

12 GC fase 1: Mark NextObjPtr Oggetti vivi Oggetti non raggiungibili Spazio libero Root set

13 GC fase 2: Compact NextObjPtr Oggetti vivi Spazio libero Root set Spazio recuperato

14 Finalization queue Gli oggetti che possiedono un finalizer non possono essere subito raccolti dal GCGli oggetti che possiedono un finalizer non possono essere subito raccolti dal GC In C# il distruttore è sinonimo di FinalizeIn C# il distruttore è sinonimo di Finalize Chiamata del finalizer dopo collectionChiamata del finalizer dopo collection Alla creazione di un oggetto che possiede Finalize, viene aggiunto un riferimento alloggetto nella Finalization queueAlla creazione di un oggetto che possiede Finalize, viene aggiunto un riferimento alloggetto nella Finalization queue Durante il GC, gli oggetti referenziati solo da Finalization queue finiscono in F-reachable queueDurante il GC, gli oggetti referenziati solo da Finalization queue finiscono in F-reachable queue

15 F-reachable queue F-reachable queue contiene riferimento a oggetti con finalizer da richiamareF-reachable queue contiene riferimento a oggetti con finalizer da richiamare Alimentata da Finalization queueAlimentata da Finalization queue I riferimenti contenuti da Finalization e F-reachable queue diventano parte del root setI riferimenti contenuti da Finalization e F-reachable queue diventano parte del root set

16 F-reachable queue Oggetti vivi In attesa di Finalize Spazio libero Root set F-reachable queue

17 F-reachable queue F-reachable queue viene smaltita in un thread dedicato che agisce in backgroundF-reachable queue viene smaltita in un thread dedicato che agisce in background GC.WaitForPendingFinalizer() per attendere che F-reachable queue sia vuotaGC.WaitForPendingFinalizer() per attendere che F-reachable queue sia vuota Ordine di chiamata su Finalize() non segue eventuali gerarchie padre-figlioOrdine di chiamata su Finalize() non segue eventuali gerarchie padre-figlio Per queste esigenze usare Dispose()Per queste esigenze usare Dispose() Evitare di implementare Finalize se non è necessario (migliori prestazioni)Evitare di implementare Finalize se non è necessario (migliori prestazioni)

18 Pattern IDisposable In alcuni casi serve un comportamento di finalizzazione deterministica:In alcuni casi serve un comportamento di finalizzazione deterministica: Riferimenti a oggetti non gestitiRiferimenti a oggetti non gestiti Utilizzo di risorse che devono essere rilasciate appena termina il loro utilizzoUtilizzo di risorse che devono essere rilasciate appena termina il loro utilizzo Non si possono usare i finalizzatori, che non sono richiamabili direttamenteNon si possono usare i finalizzatori, che non sono richiamabili direttamente Implementare linterfaccia IDisposableImplementare linterfaccia IDisposable

19 Pattern IDisposable (1) class DisposeDemo : BaseClass, IDisposable { OtherRes otherRes; OtherRes otherRes; private disposed = false; private disposed = false; private void freeState { private void freeState { if (!disposed) { // Evita doppia esecuzione if (!disposed) { // Evita doppia esecuzione // Chiude risorse allocate (es. handle non gestiti) // Chiude risorse allocate (es. handle non gestiti) disposed = true; disposed = true; } } public void Dispose() { public void Dispose() { freeState(); freeState(); otherRes.Dispose();// Dispose oggetti membro otherRes.Dispose();// Dispose oggetti membro base.Dispose(); // Dispose classe base (BaseClass) base.Dispose(); // Dispose classe base (BaseClass) GC.SuppressFinalize( this ); GC.SuppressFinalize( this ); } ~DisposeDemo() { ~DisposeDemo() { freeState(); freeState(); }}

20 Pattern IDisposable (2 a) class BaseResource : IDisposable { OtherRes otherRes; OtherRes otherRes; private disposed = false; private disposed = false; protected virtual void Dispose( bool disposing ) { protected virtual void Dispose( bool disposing ) { if (!this.disposed) { if (!this.disposed) { if (disposing) { if (disposing) { otherRes.Dispose(); // Dispose oggetti membro otherRes.Dispose(); // Dispose oggetti membro } CloseHandle(... ); // Chiude risorse non gestite CloseHandle(... ); // Chiude risorse non gestite this.disposed = true; this.disposed = true; } } public void Dispose() { public void Dispose() { Dispose( true ); Dispose( true ); GC.SuppressFinalize( this ); GC.SuppressFinalize( this ); } ~DisposeDemo() { ~DisposeDemo() { Dispose( false ); Dispose( false ); }}

21 Pattern IDisposable (2 b) class MyResource : BaseResource { // Implementa già IDisposable private disposed = false; private disposed = false; protected override void Dispose( bool disposing ) { protected override void Dispose( bool disposing ) { if (!this.disposed) { if (!this.disposed) { if (disposing) { if (disposing) { // Dispose altri oggetti gestiti // Dispose altri oggetti gestiti } // Chiude risorse non gestite // Chiude risorse non gestite this.disposed = true; this.disposed = true; } base.Dispose(); base.Dispose(); } // La funzione Dispose() è già implementata nella classe base // La funzione Dispose() è già implementata nella classe base // Il finalizzatore che chiama Dispose(bool) virtuale è già // Il finalizzatore che chiama Dispose(bool) virtuale è già // implementato nella classe base // implementato nella classe base}

22 Componenti.NET System.ObjectSystem.Object Non implementa nessuna interfacciaNon implementa nessuna interfaccia System.ComponentModel.ComponentSystem.ComponentModel.Component Implementa IDisposable col pattern (2)Implementa IDisposable col pattern (2) Deriva da MarshalByRefObjectDeriva da MarshalByRefObject System.Windows.Forms.ControlSystem.Windows.Forms.Control Deriva da System.ComponentModel.ComponentDeriva da System.ComponentModel.Component Controlli progettabili graficamenteControlli progettabili graficamente Per controlli interattivi derivare UserControlPer controlli interattivi derivare UserControl System.Web.UI.ControlSystem.Web.UI.Control Implementa IDisposable col pattern (1)Implementa IDisposable col pattern (1)

23 Resurrection Chiamare GC.SuppressFinalize() per eliminare loggetto da F-reachable queueChiamare GC.SuppressFinalize() per eliminare loggetto da F-reachable queue Finalize() non verrà più richiamataFinalize() non verrà più richiamata Un oggetto può ri-registrare il finalizzatore chiamando GC.ReRegisterForFinalize()Un oggetto può ri-registrare il finalizzatore chiamando GC.ReRegisterForFinalize() Tecnica chiamata resurrectionTecnica chiamata resurrection In Finalize() si assegna this ad un oggetto raggiungibile da root setIn Finalize() si assegna this ad un oggetto raggiungibile da root set GC.ReRegisterForFinalize() garantisce la successiva ri-esecuzione di Finalize()GC.ReRegisterForFinalize() garantisce la successiva ri-esecuzione di Finalize() Da non usare se non si è più che sicuri !!Da non usare se non si è più che sicuri !!

24 Resurrection public class BaseObj { //... //... ~BaseObj() { ~BaseObj() { Application.ObjHolder = this; Application.ObjHolder = this; GC.ReRegisterForFinalize( this ); GC.ReRegisterForFinalize( this ); } //... //...} class Application { static public Object ObjHandler; static public Object ObjHandler; //... //...}

25 Weak Reference Un Weak Reference è un riferimento debole ad un oggettoUn Weak Reference è un riferimento debole ad un oggetto Non viene considerato come riferimento da parte del Garbage CollectorNon viene considerato come riferimento da parte del Garbage Collector Se loggetto viene raccolto dal GC, il Weak Reference vale nullSe loggetto viene raccolto dal GC, il Weak Reference vale null Utile per meccanismi di cacheUtile per meccanismi di cache Esistono due tipi di Weak Reference:Esistono due tipi di Weak Reference: Short Weak ReferenceShort Weak Reference Long Weak ReferenceLong Weak Reference

26 Weak Reference Short Weak ReferenceShort Weak Reference Valido fino a che loggetto non viene finalizzatoValido fino a che loggetto non viene finalizzato Long Weak ReferenceLong Weak Reference Valido anche dopo la finalizzazioneValido anche dopo la finalizzazione Utilizzabile per Resurrection - consente di chiamare GC.ReRegisterForFinalize()Utilizzabile per Resurrection - consente di chiamare GC.ReRegisterForFinalize() WeakReference( Object target ); WeakReference( Object target ); WeakReference( Object target, Boolean trackResurrection ); WeakReference( Object target, Boolean trackResurrection );

27 Algoritmo generazionale Ottimizzazione dellalgoritmo di GCOttimizzazione dellalgoritmo di GC Statisticamente gli oggetti più giovani hanno una vita più breveStatisticamente gli oggetti più giovani hanno una vita più breve Il GC definisce letà in base alla durata della presenza sullheapIl GC definisce letà in base alla durata della presenza sullheap Generazione: insieme di elementi che sopravvivono ad un GCGenerazione: insieme di elementi che sopravvivono ad un GC Le generazioni più vecchie vengono analizzate dal GC meno soventeLe generazioni più vecchie vengono analizzate dal GC meno sovente

28 Algoritmo generazionale Ad ogni GC gli oggetti che sopravvivono vengono promossi di una generazioneAd ogni GC gli oggetti che sopravvivono vengono promossi di una generazione Limplementazione attuale definisce 3 generazioniLimplementazione attuale definisce 3 generazioni G2 Oggetti sopravvissuti a due o più GC G1 Oggetti sopravvissuti a un GC G0 Oggetti mai sottoposti a GC

29 Algoritmo generazionale GC.GetGeneration() restituisce la generazione di un oggettoGC.GetGeneration() restituisce la generazione di un oggetto Frequenza GC su generazioni più vecchie fino a 1/10 di quelle recentiFrequenza GC su generazioni più vecchie fino a 1/10 di quelle recenti Il GC non segue i riferimenti che puntano a generazioni più vecchieIl GC non segue i riferimenti che puntano a generazioni più vecchie GC.Collect( n ) consente di specificare quante generazioni esaminareGC.Collect( n ) consente di specificare quante generazioni esaminare Gli oggetti con Finalize() vengono promossi almeno una voltaGli oggetti con Finalize() vengono promossi almeno una volta

30 Large Object Heap Heap separato per oggetti di grandi dimensioni (>20k)Heap separato per oggetti di grandi dimensioni (>20k) Il loro spostamento è costosoIl loro spostamento è costoso Di solito non sono frequentiDi solito non sono frequenti Gli oggetti non vengono spostatiGli oggetti non vengono spostati Simile a un tradizionale heap C/C++Simile a un tradizionale heap C/C++

31 Thread e Garbage Collector Versioni di GC diverse per mono e multi- processoreVersioni di GC diverse per mono e multi- processore Ogni processo ha un thread separato per chiamare i Finalize() degli oggettiOgni processo ha un thread separato per chiamare i Finalize() degli oggetti Priorità più alta non real-timePriorità più alta non real-time I metodi Finalize() vengono sempre chiamati da questo threadI metodi Finalize() vengono sempre chiamati da questo thread Loperazione di GC arresta tutti i thread gestiti (root set deve essere noto)Loperazione di GC arresta tutti i thread gestiti (root set deve essere noto) Thread hijackingThread hijacking Safe pointsSafe points Fully interruptible codeFully interruptible code

32 Thread hijacking In presenza di un metodo breve, lindirizzo di ritorno viene deviato verso il GC, che ritorna poi al percorso originaleIn presenza di un metodo breve, lindirizzo di ritorno viene deviato verso il GC, che ritorna poi al percorso originale int bar() { return 42; return 42;} int foo() { int ret = bar(); int ret = bar(); return ret; return ret;} GC

33 Safe Points In metodi lunghi il jitter inserisce delle chiamate che sospendono il thread se deve essere eseguito il GCIn metodi lunghi il jitter inserisce delle chiamate che sospendono il thread se deve essere eseguito il GC int bar() { } GC Se GC in attesa, sospende il thread fino a che il GC non viene completato GC Safe Point

34 Fully interruptible code In loop stretti il thread viene sospeso ed il GC esamina una tabella generata dal jitter con gli oggetti attivi (root set) ad ogni lineaIn loop stretti il thread viene sospeso ed il GC esamina una tabella generata dal jitter con gli oggetti attivi (root set) ad ogni linea while (condition) { 09 Foo a = new Foo(); 10 Bar b = new Bar(); 11 Foo c = new Foo(); a.DoSomething(); 14 condition = c.Good(); 15 } LineaOggetti 09{} 10{a} 11{a,c} 12{a,c} 13{c} 14{}

35 Concurrent Garbage Collector Configurabile a livello di host CLRConfigurabile a livello di host CLR Parametro flags di CorBindToRuntimeEx()Parametro flags di CorBindToRuntimeEx() ConcurrentGCConcurrentGC Non rallenta interfaccia utenteNon rallenta interfaccia utente Prestazioni complessive più bassePrestazioni complessive più basse Costruzione del grafo di raggiungibilità in backgroundCostruzione del grafo di raggiungibilità in background Non-concurrent GCNon-concurrent GC Agisce nello stesso thread del codice utenteAgisce nello stesso thread del codice utente Migliori prestazioni complessiveMigliori prestazioni complessive Indicato per applicazioni serverIndicato per applicazioni server Default in file configurazione runtime:Default in file configurazione runtime:

36 Garbage Collector vs. Heap Win32 Allocazione più veloceAllocazione più veloce Penalizzazione se loggetto ha FinalizePenalizzazione se loggetto ha Finalize Anche lallocazione è più lentaAnche lallocazione è più lenta Importante chiamare GC.SuppressFinalize() su Dispose()Importante chiamare GC.SuppressFinalize() su Dispose() Heap C++ per build Debug estremamente più lento (anche volte)Heap C++ per build Debug estremamente più lento (anche volte) Paragone difficileParagone difficile Il finalizzatore può essere richiamato in background, mentre il distruttore è sempre sincrono nel thread chiamanteIl finalizzatore può essere richiamato in background, mentre il distruttore è sempre sincrono nel thread chiamante

37 Considerazioni finali Non interagire direttamente con GC se non cè un buon motivoNon interagire direttamente con GC se non cè un buon motivo Tentare di risolvere un bug chiamando GC.Collect() non è un buon motivo!Tentare di risolvere un bug chiamando GC.Collect() non è un buon motivo! Evitare finalizzatori se le prestazioni sono importantiEvitare finalizzatori se le prestazioni sono importanti Va più veloce della gestione Heap tradizionaleVa più veloce della gestione Heap tradizionale Weak reference e Resurrection solo se cè un ottimo motivoWeak reference e Resurrection solo se cè un ottimo motivo Evitare di creare più problemi di quanti se ne risolvonoEvitare di creare più problemi di quanti se ne risolvono

38 Riferimenti utili Demo di tutte le funzionalità di GC:Demo di tutte le funzionalità di GC: C:\Program Files\Microsoft.NET\FrameworkSDK\Samples\ technologies\GarbageCollection Articoli di Jeffrey Richter su MSDN Magazine:Articoli di Jeffrey Richter su MSDN Magazine: us/dnmag00/html/GCI.asp us/dnmag00/html/GCI2.asp

39 Altre Informazioni Dove posso ottenere maggiori informazioniDove posso ottenere maggiori informazioni msdn.microsoft.commsdn.microsoft.com Developer resourcesDeveloper resources Microsoft Visual Studio.NETMicrosoft Visual Studio.NET Microsoft.NET Framework SDKMicrosoft.NET Framework SDK Microsoft Developer NetworkMicrosoft Developer Network

40 Gestione della memoria e delle risorse in.NET I vostri feedback sono importanti ScriveteciScriveteci Grazie della partecipazione –A presto


Scaricare ppt "Gestione della memoria e delle risorse in.NET Marco Russo MCSD MCAD MCSE+I MCSA MCDBA MCT Mail: Italian blog:"

Presentazioni simili


Annunci Google