360 likes | 484 Views
Programowanie Aplikacji Lokalnych w Środowisku .NET. Organizacja pamięci Samodzielne zarządzanie pamięcią Pamięć w .NET. Pamięć > 2GB.
E N D
ProgramowanieAplikacjiLokalnychw Środowisku .NET Organizacja pamięci Samodzielne zarządzanie pamięcią Pamięć w .NET
Pamięć > 2GB • W systemach 32b (począwszyod Windows 2000 Advanced Server), Windows XP Pro możnazredukowaćprzestrzeńjądra do 1GB (iuzyskać 3GB w trybieużytkownika) • /3GB w boot.ini • linker - /LARGEADDRESWARE • Problemy z kompatybilnościąprzyniestand. wykorzystaniuprzezprogramistówgórnegobituwskaźnika do • Żeby zobaczyć więcejniż 3GB system musi pracować w trybie PAE –> pot. problemy ze sterownikami • Windows 64B – 4TB
Operacjenapamięci (Win32) • dwaetapypobieraniablokupamięciVirtualAlloc • rezerwacjaMEM_RESERVE • przydzielenieMEM_COMMIT • dwaetapyzwalnianiablokupamięciVirtualFree • oddzielenieMEM_DECOMMIT • przydzielanieMEM_RELEASE • atrybutydostępu do blokupamięciVirtualProtect • blokowaniezrzucaniapamięcinadyskVirtualLock / Unlock
Pamięć wirtualna – dostęp • VirtualAlloc najpierw sprawdza czy pamięć już została zamapowana i ew. nie robi tego ponownie. • Próba dostępu do pamięci zarezerwowanej, ale nie przydzielonej generuje wyjątek (ktory można obsłużyć)
Stan pamięci statystykasystemu: • GlobalMemoryStatus: 32Bit -> przestrzeń 4GB • 2GB aplikacja 2GB system • 3GB+1GB – system boot.ini: „/3GB”orazIMAGE_FILE_LARGE_ADDRESS_AWARE dlaaplikacji • 64Bit -> >4GB .NET: • System.Management.ManagementClass("Win32_OperatingSystem") • System.Management.ManagementClass.GetInstances • System.Management.ManagementObject.Properties stanprzestrzeniadresowej: • VirtualQuery • VirtualQueryEx(hProcess, ...)
Reprezentacjadanych Typywartościowe: • typyproste, stuktury • alokowanenastosie • niemożnaponichdziedziczyć Typyreferencyjne: • obiekty • alokowanenasterciezarządzalnej • unikatowatożsamość • dodatkowepola (sync block, Method Table Pointer )
Reprezentacja Kolejnośćpól • LayoutKind.Auto — o kolejnościułożeniadecyduje CLR. • LayoutKind.Sequential — kolejnośćułożeniaodpowiadakolejnościdefinicjipólobiektu w kodzieźródłowym. • LayoutKind.Explicit – kolejność jest określonaprzezpodaniekonkretnychoffset’ów. • Boxing/unboxing
Boxing/unboxing structPktValue { public byte X; publicbyte Y; } Object Test(Object obj) { return obj; } PktValuev = new PktValue(); Object o = Test(v); v = (PktValue) o; Kolekcjegeneryczne Przeciązaniematod Equals, ImplementacjaEquatable<T>,IComparable<T>
interface IChangeBoxedPoint { void Change(Int32 x, Int32 y); } struct Point : IChangeBoxedPoint { private Int32 m_x, m_y; public Point(Int32 x, Int32 y) { m_x= x; m_y= y; } public void Change(Int32 x, Int32 y) { m_x= x; m_y = y; } public override String ToString() { return String.Format("({0}, {1})", m_x.ToString(), m_y.ToString()); } };
Point p = new Point(1, 1); // 1 Console.WriteLine(p); // 2 p.Change(2, 2); // 3 Console.WriteLine(p); // 4 Object o = p; // 5 Console.WriteLine(o); // 6 ((Point) o).Change(3, 3); // 7 Console.WriteLine(o); // 8 ((IChangeBoxedPoint) p).Change(4, 4); // 9 Console.WriteLine(p); // 10 ((IChangeBoxedPoint) o).Change(5, 5); // 11 Console.WriteLine(o); //12
Point p = new Point(1, 1); // 1 Console.WriteLine(p); // 2 Konwersja p.Change(2, 2); // 3 Console.WriteLine(p); // 4 Konwersja Object o = p; // 5 Konwersja + pot. niespójność -> 2 kopie Console.WriteLine(o); // 6 ? ((Point) o).Change(3, 3); // 7 Konwersjajaka jest zawartość o? Console.WriteLine(o); // 8 ((IChangeBoxedPoint) p).Change(4, 4); // 9 Konwersja+ zaw. p? Console.WriteLine(p); // 10 Konwersja ((IChangeBoxedPoint) o).Change(5, 5); // 11 Console.WriteLine(o); //12
Życieobiektuwg. GC • Rezerwacja - new (IL->newobj) • Inicjalizacja (konstruktor) • Użycie • Deterministyczneuwolnieniezasobów(Dispose) • Zaznaczanienieużytków (Mark) • Ew. Uwolnieniezasobów (Finalizacja) • Zwolnieniepamieci(Sweep&Pack)
GC Mark&Sweep&Compact GC - Poszukuje o oznaczaobiekty, któremająkorzeń w • zmiennychstatycznych • zmiennychlokalnych • referencjachmiedzy-generacyjnych • obiektach w kolejce do finalizacji Niezaznaczoneobiektyusuwaikompaktujestertę
Sterta zarządzana • Przydziałniewymagaprzeglądania list wolnychbloków) • Możliwa jest reorganizacjasterty
Obiektyiśmieci Zaznaczanesą: • statyczneobiekty • Lokalneobiekty • paramertyfunkcji • Obiektybędącewłasnościąówjużjużzaznaczonych W momenciebrakupamięciprzeprowadzane jest odśmiecanie
Ile razywykonasię GC? class Program { static void Main(string[] args) { Timer timer = new Timer(OnTimer, null, 0, 1000); Console.ReadLine(); } static void OnTimer(object state) { GC.Collect(); // wymuszeniepracy GC } }
Ile razywykonasię GC? class Program { static void Main(string[] args) { Timer timer = new Timer(OnTimer, null, 0, 1000); Console.ReadLine(); } static void OnTimer(object state) { GC.Collect(); // wymuszeniepracy GC } } • 1 raz – optymalizacja: kompilator “zapamietujemiejsce do którego jest używanazmiennalokalna”
Generacje • Założenia: • starszeobiektyżyjądłużej, • starszeobiektysąpotencjalniesilniejzwiązane • Po zakończeniuoznaczaniausuwanesąmartweobiekty z b. Pokolenia a żywesąprzemieszczane
Generacje • Sprzątanie Gen 0 – 1ms? • Gen 1 – domyslnie 0.5-4MB • Przypięteobiektysąpromowane • Wolania m. generacyjne (sprawdzane w momencieprzypisania) Stertadużychobiektów (>85KB dla.Net <=4.5.1) • Odrazutrafiajądigeneracji 2 • Niepodlegakompaktowaniu (odwersji 4.5.1 jest to możliwe jest ale tylkonarządanie) • Zarządzanapoprzezlistęwolnychmiejsc
Zarządzanie automatem • void GC.Collect(Int32 Generation) • void GC.Collect() GC.Collect(GC.MaxGeneration); • Int32 GetGeneration(Object obj) • void WaitForPendingFinalizers();
Konfiguracja GC Wokstation -> pracaprzyjednymprocesorze Niewspółbieżna – wszystkiewątkiroboczesązawieszonenacałyczassprzątania Współbieżna – przed.Net 4.0 większaczęśćfazyoznaczania jest wykonywanwspółbieżnie (2 generacja) Współbieżna – od.Net 4.0 2 wątki I foreground blokującoodśmieca 0,1 generacjęorazupakowuje 2 II background jest nieblokujący I odznacza (ale nieupakowuje) 2 generację
Konfiguracja GC Serwer -> każdyprocesor ma swojąstertę, alokacja I sprzątanieodbywająsierównolegle. Od 4.5 Praca w tle (2 wątki – analogicznie do workstation) Zbalansowanaalokacjadużychobiektów – rownomiernierozłożonanawszystkiesterty • GC.Collect(2, GCCollectionMode.Optimized) • GCCollectionMode: Default | Forced | Optimized.
Konfiguracja GC Batch – aplikacjebez GUI/operacjiserwerowych <gcConcurrent> jest zablokowanyluboba <gcConcurrent> i <gcServer> sąwłączone. Interactive – GUI <gcConcurrent> is włączonyi <gcServer> is zablokowany LowLatency – aplikacje z wymaganymkrótkimczasemodpowiedzi, wrażliwenaspowolnieniespowodowaneprzez GC (-> renderowaniegrafiki?) SustainedLowLatency: (od .NET 4.5)zarówno dla trybu stacji roboczej,jak i serwera. Pozwalaodwlekać pełne odzyskiwaniepamięci dladługotrwałychoperacji. GCSettings.LatencyMode = GCLatencyMode.SustainedLowLatency
Uwalnianiezasobów Na życzenie: Dispose Automatyczne: Finalizator
IDisposeable // Font : IDisposeable; Font font1 = new Font("Arial", 10.0f) ... font1.Dispose(); // finally? using (Font font1 = new Font("Arial", 10.0f)) { } Gdziezwalniany jest obiekt?
Finalizator • Jest przeznaczony do zwalnianiazasobów • Finalizatoraniedefiniujesieexplicite • Finalizator jest generowanyautomatycznie - > destruktor public class BaseObj {public BaseObj() {}public ~ BaseObj () { // zwalnianiezasobównp. Close(db_connection);Console.WriteLine("In Finalize.");} /* protected override void Finalize() { // zwalnianiezasobównp. Close(db_connection);Console.WriteLine("In Finalize."); }*/
Finalizator Obiektyzawierającefinalizator • sąwolniejalokowane, dużo wolniejzwalniane • domyślnie „żyjąjednągeneracjędłużej” • dotyczy to równieżwszystkichobiektów, do którychodwołujasiętakieobiektyitd. • nie jest znanakolejnośćwołańfinalizatorów • nie ma gwarancjizefinalizatorzostanieuruchomiony MyObject : CriticalFinalizerObject voidWaitForPendingFinalizers() w przypadku zabicia procesu nicnie pomoże • F. niesawołanedomyslniedlaklasbazowych (por. destruktor)
Kolejkado finalizacji kolejka obiektów do finalizacji – nie mogą one zostać usuniete bez finalizacji
Kolejka do finalizacji kolejka obiektów po finalizacji ale przed dealokacją powód: w jednej z kolejek (istniejąobiektyposiadające do nichwskaźnik)
Wskrzeszenieobiektu? Powód: W czasiefinalizacjipowstajenowareferencja do obiektu • rzucany jest wyjątek (tragedia!!!) • przypisujemycoś do wskaźnikaglobalnego, statycznego, atrybutu „żyjącegoobiektu” Problem: • obiektmożebyćjuż „sfinalizowany” Rozwiązanie: • flaga – „finalizacjaukończona” wykluczająca operacje Sterowanie mechanizmem finalizacji – przydatne gdy chcemy finallizować na życzenie GC.ReRegisterForFinalize(this); GC.SuppressFinalize(this);
Pattern Finalize/Dispose public class MyClass : IDisposable {private bool disposed = false;~MyResource() {Dispose (false);} public void Dispose() // Do not make this method virtual.{ Dispose (true);} public void Close() // Do not make this method virtual.{ Dispose (true);}
Zwolnienie na życzenie private void Dispose(bool disposing){// Check to see if Dispose has already been called.if(!this.disposed) {if(disposing) {AllComponent.Dispose(); GC.SuppressFinalize(this); } CloseHandle(handle); handle = IntPtr.Zero; disposed = true; }}
Słabe referencje void Method() {Object o = new Object(); // silnareferencjaWeakReferencewr = new WeakReference(o);o = null; // usuwamysilnąreferencjęo = wr.Target; if (o == null) { // GC zwolniłobiekt} else { // obiektciągleistnieje} }
Czy jest możliwywyciekpamięci w .NET? btn.Click+= OnBtnClick
Monitorowanie GC System.Diagnostics.PerformanceCounter
Critical Object Finalizers Podczas tworzenia pierwszego obiektu danego typu, metoda finalizującajest kompilowana przez kompilator JIT (minimalizujemyryzykowystąpienia błędu braku pamięci potem – brakkompilacjiprzypierwszymwołaniu) Finalizator jest wykonywany powszyskichfinalizatorachobiektówzwykłych CLR wywołuje metodę finalizacji nawet gdy AppDomainjest niespodziewaniezamykana przez aplikację hostującą (np. IIS). Ale niemożliwe jest dziedziczeniepoinnymobiekcie(brakwielodziedziczenia)