1. Gestione della memoria e delle risorse in .NET Marco Russo MCSD MCAD MCSE+I MCSA MCDBA MCT Mail: marco@devleap.it Italian blog: http://blogs.devleap.com/marco.blog
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
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
19. Pattern IDisposable (1) class DisposeDemo : BaseClass, IDisposable { OtherRes otherRes; private disposed = false; private void freeState { if (!disposed) { // Evita doppia esecuzione // Chiude risorse allocate (es. handle non gestiti) disposed = true; } } public void Dispose () { freeState(); otherRes.Dispose();// Dispose oggetti membro base.Dispose(); // Dispose classe base (BaseClass) GC.SuppressFinalize ( this ); } ~DisposeDemo() { freeState(); } }
20. Pattern IDisposable (2 a) class BaseResource : IDisposable { OtherRes otherRes; private disposed = false; protected virtual void Dispose( bool disposing ) { if (!this.disposed) { if (disposing) { otherRes.Dispose(); // Dispose oggetti membro } CloseHandle( ... ); // Chiude risorse non gestite this.disposed = true; } } public void Dispose () { Dispose( true ); GC.SuppressFinalize ( this ); } ~DisposeDemo() { Dispose( false ); } }
21. Pattern IDisposable (2 b) class MyResource : BaseResource { // Implementa già IDisposable private disposed = false; protected override void Dispose( bool disposing ) { if (!this.disposed) { if (disposing) { // Dispose altri oggetti gestiti } // Chiude risorse non gestite this.disposed = true; } base.Dispose(); } // La funzione Dispose() è già implementata nella classe base // Il finalizzatore che chiama Dispose(bool) virtuale è già // implementato nella classe base }
22.
23.
24. Resurrection public class BaseObj { // ... ~BaseObj() { Application.ObjHolder = this; GC.ReRegisterForFinalize( this ); } // ... } class Application { static public Object ObjHandler; // ... }
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
Notas del editor
Bisogna specificare che i thread devono essere fermati in punti noti , in modo che il GC possa sapere quali sono gli oggetti che fanno parte del root set (variabili locali sull’albero di chiamata di ogni thread)