Zarządzanie pamięcią: ręczne czy automatyczne

Post on 11-Jan-2016

72 views 0 download

description

Zarządzanie pamięcią: ręczne czy automatyczne. Łukasz Kosson Tomasz Wasersztrum. Podstawy. Podstawy. Stos i sterta. Podstawy. Stos i sterta. Podstawy. Stos i sterta malloc() i free(). Podstawy. Stos i sterta malloc() i free() (implementacja windows). Podstawy. Stos i sterta - PowerPoint PPT Presentation

Transcript of Zarządzanie pamięcią: ręczne czy automatyczne

Zarządzanie pamięcią: ręczne czy automatyczne

Łukasz Kosson

Tomasz Wasersztrum

Podstawy

Podstawy

Stos i sterta

Podstawy

Stos i sterta

Podstawy

Stos i sterta malloc() i free()

Podstawy

Stos i sterta malloc() i free() (implementacja windows)

Podstawy

Stos i sterta malloc() i free() (implementacja windows)

tablica wolnych bloków

Podstawy

Stos i sterta malloc() i free() (implementacja windows)

tablica wolnych bloków bloki „zawieszone”

Podstawy

Stos i sterta malloc() i free() (implementacja windows)

tablica wolnych bloków bloki „zawieszone” schemat algorytmów

Podstawy

Stos i sterta malloc() i free() (implementacja windows)

tablica wolnych bloków bloki „zawieszone” schemat algorytmów

new i delete

Problemy zarządzania pamięcią

Problemy zarządzania pamięcią Wycieki pamięci (memory leak)

Problemy zarządzania pamięcią Wycieki pamięci (memory leak)

Pseudokod obsługi windy.

Problemy zarządzania pamięcią Wycieki pamięci (memory leak)

Pseudokod obsługi windy.

When a button is pressed:  Get some memory, which will be used to remember the floor number  Put the floor number into the memory  Are we already on the target floor?  If so, we have nothing to do: finished  Otherwise:    Wait until the lift is idle     Go to the required floor    Release the memory we used to remember the floor number

Problemy zarządzania pamięcią Wycieki pamięci (memory leak)

Problemy zarządzania pamięcią Wycieki pamięci (memory leak) Nieaktualne referencje (dangling pointers)

Problemy zarządzania pamięcią Wycieki pamięci (memory leak) Nieaktualne referencje (dangling pointers) Fragmentacja

Garbage collector

Garbage collector

Czym jest i co robi?

Garbage collector

Czym jest i co robi? Jeden z mechanizmów zarządzania zasobami (m.in. pamięcią)

Garbage collector

Czym jest i co robi? Jeden z mechanizmów zarządzania zasobami (m.in. pamięcią) Odpowiedzialny za zwalnianie niepotrzebnych zasobów

Garbage collector

Czym jest i co robi? Jeden z mechanizmów zarządzania zasobami (m.in. pamięcią) Odpowiedzialny za zwalnianie niepotrzebnych zasobów Często zmniejsza fragmentację (zewnętrzną i wewnętrzną) pamięci

Garbage collector

Czym nie jest i czego nie robi?

Garbage collector

Czym nie jest i czego nie robi? Nie zwalnia z racjonalnego korzystania z pamięci

Garbage collector

Czym nie jest i czego nie robi? Nie zwalnia z racjonalnego korzystania z pamięci Nie służy do wykrywania wycieków

Garbage collector

Czym nie jest i czego nie robi? Nie zwalnia z racjonalnego korzystania z pamięci Nie służy do wykrywania wycieków Nie dotyka zewnętrznych zasobów

Garbage collector

Czym nie jest i czego nie robi? Nie zwalnia z racjonalnego korzystania z pamięci Nie służy do wykrywania wycieków Nie dotyka zewnętrznych zasobów Nie czyni cudów

Garbage collector

Gdzie jest wykorzystywany?

Garbage collector

Gdzie jest wykorzystywany? Początki: LISP, 1960

Garbage collector

Gdzie jest wykorzystywany? Początki: LISP, 1960 Głównie wykorzystywany do zarządzania pamięcią operacyjną ...

Garbage collector

Gdzie jest wykorzystywany? Początki: LISP, 1960 Głównie wykorzystywany do zarządzania pamięcią operacyjną ... ... ale także np. połączeniami, plikami

Garbage collector

Gdzie jest wykorzystywany? Początki: LISP, 1960 Głównie wykorzystywany do zarządzania pamięcią operacyjną ... ... ale także np. połączeniami, plikami Środowiska, np: .NET, JVM (także ME)

Garbage collector

Gdzie jest wykorzystywany? Początki: LISP, 1960 Głównie wykorzystywany do zarządzania pamięcią operacyjną ... ... ale także np. połączeniami, plikami Środowiska, np: .NET, JVM (także ME) Języki skryptowe, np JavaScript

GC – zasada działania

Jakie obiekty sprzątać?

GC – zasada działania

Jakie obiekty sprzątać? Optymalne rozwiązanie: kasować obiekty nieosiągalne

semantycznie

GC – zasada działania

Jakie obiekty sprzątać? Optymalne rozwiązanie: kasować obiekty nieosiągalne

semantycznie Problem: zagadnienie równoważne problemowi stopu.

GC – zasada działania

Jakie obiekty sprzątać? Optymalne rozwiązanie: kasować obiekty nieosiągalne

semantycznie Problem: zagadnienie równoważne problemowi stopu. Prostsze rozwiązanie: osiągalność syntaktyczna

GC – zasada działania

Jakie obiekty sprzątać? Optymalne rozwiązanie: kasować obiekty nieosiągalne

semantycznie Problem: zagadnienie równoważne problemowi stopu. Prostsze rozwiązanie: osiągalność syntaktyczna Praktyka: rozwiązanie pośrednie

GC – zasada działania

Algorytm naiwny (mark and sweep):

GC – zasada działania

Algorytm naiwny (mark and sweep): Dla każdego obiektu trzymamy bit osiągalności

GC – zasada działania

Algorytm naiwny (mark and sweep): Dla każdego obiektu trzymamy bit osiągalności Zaczynając od obiektów bezpośrednio osiągalnych przeglądamy

strukturę obiektów

GC – zasada działania

Algorytm naiwny (mark and sweep): Dla każdego obiektu trzymamy bit osiągalności Zaczynając od obiektów bezpośrednio osiągalnych przeglądamy

strukturę obiektów Zwalniamy obiekty do których się nie udało dojść

GC – zasada działania

Wady algorytmu naiwnego:

GC – zasada działania

Wady algorytmu naiwnego: Wymaga wstrzymania procesu

GC – zasada działania

Wady algorytmu naiwnego: Wymaga wstrzymania procesu Przeglądanie całej pamięci

GC – zasada działania

Wady algorytmu naiwnego: Wymaga wstrzymania procesu Przeglądanie całej pamięci Duża fragmentacja pamięci

GC – zasada działania

Modyfikacje algorytmu mark-and-sweep:

GC – zasada działania

Modyfikacje algorytmu mark-and-sweep: Stop-and-copy: redukuje fragmentację, ale zwiększa dwukrotnie

wymagania pamięciowe

GC – zasada działania

Modyfikacje algorytmu mark-and-sweep: Stop-and-copy: redukuje fragmentację, ale zwiększa dwukrotnie

wymagania pamięciowe Mark-and-compact: redukuje fragmentację

GC – zasada działania

Obserwacja: Im obiekt młodszy, tym szybciej staje się niedostępny

GC – zasada działania

Obserwacja: Im obiekt młodszy, tym szybciej staje się niedostępny

Wniosek: Nie traktować wszystkich obiektów jednakowo

GC – zasada działania

Obserwacja: Im obiekt młodszy, tym szybciej staje się niedostępny

Wniosek: Nie traktować wszystkich obiektów jednakowo

Pomysł: Algorytmy pokoleniowe

GC – zasada działania

Obserwacja: Im obiekt młodszy, tym szybciej staje się niedostępny

Wniosek: Nie traktować wszystkich obiektów jednakowo

Pomysł: Algorytmy pokoleniowe

Efekt: Szybsze zwalnianie pamięci

GC – zasada działania

Współczesne GC: Rozróżnienie na obiekty młode i stare (dwie lub trzy klasy)

GC – zasada działania

Współczesne GC: Rozróżnienie na obiekty młode i stare (dwie lub trzy klasy)JVM: Obiekty młode odzyskiwane przez stop-and-copy Obiekty stare – przez mark-and-sweep

GC – zasada działania

Współczesne GC: Rozróżnienie na obiekty młode i stare (dwie lub trzy klasy)JVM: Obiekty młode odzyskiwane przez stop-and-copy Obiekty stare – przez mark-and-sweep Możliwość wymuszenia użycia innego algorytmu (w tym:

współbieżnego)

GC – zasada działania

Współczesne GC: Rozróżnienie na obiekty młode i stare (dwie lub trzy klasy)JVM: Obiekty młode odzyskiwane przez stop-and-copy Obiekty stare – przez mark-and-sweep Możliwość wymuszenia użycia innego algorytmu (w tym:

współbieżnego).NET: Wszystkie pokolenia obsługiwane przez mark-and-compact

GC – jak mu pomóc

GC – jak mu pomóc

Weak reference:

GC – jak mu pomóc

Weak reference: Działa jak zwykły wskaźnik ...

GC – jak mu pomóc

Weak reference: Działa jak zwykły wskaźnik ... ... ale nie jest traktowany przez GC jako referencja

GC – jak mu pomóc

Weak reference: Działa jak zwykły wskaźnik ... ... ale nie jest traktowany przez GC jako referencja Szczególnie przydatny przy implementowaniu pamięci podręcznej

GC – jak sobie pomóc

GC – jak sobie pomóc

Finalizacja:

GC – jak sobie pomóc

Finalizacja: Mechanizm zastępujący destruktory

GC – jak sobie pomóc

Finalizacja: Mechanizm zastępujący destruktory Kwestia wydajności

GC – jak sobie pomóc

Finalizacja: Mechanizm zastępujący destruktory Kwestia wydajności A co gdy korzystamy z zewnętrznych zasobów?

GC – środowiska hybrydowe

Co się dzieje w sytuacji, gdy mamy wskaźniki na obiekty?

GC – środowiska hybrydowe

Co się dzieje w sytuacji, gdy mamy wskaźniki na obiekty?unsafe{

Bitmap img = Image.FromFile(„pict.jpg”);BitmapData data = img.LockBits();byte* pixels = data.Scan0;Process(pixels);img.UnlockBits(data);

}

GC – środowiska hybrydowe

Co się dzieje w sytuacji, gdy mamy wskaźniki na obiekty?unsafe{

Bitmap img = Image.FromFile(„pict.jpg”);BitmapData data = img.LockBits();byte* pixels = data.Scan0;Process(pixels);img.UnlockBits(data);

} Odpowiedź:fixed (byte* pixels = data.Scan0){ ...}

Zamiast GC…

Zamiast GC… Zliczanie referencji

Zamiast GC…

refcountedstruct , REF() , UNREF()

Zliczanie referencji

struct refcountedstruct { int refcount;}

void REF(void *data){ struct refcountedstruct *rstruct; rstruct = (struct refcountedstruct *) data; rstruct->refcount++;}

Zamiast GC… Zliczanie referencji

void UNREF(void *data){ struct refcountedstruct *rstruct; rstruct = (struct refcountedstruct *) data; rstruct->refcount--; if(rstruct->refcount == 0) { free(rstruct); }}

refcountedstruct , REF() , UNREF()

Zamiast GC… Zliczanie referencji

struct mydata{ int refcount; int datafield;};void dosomething(struct mydata *data){

REF(data);/* Process data */UNREF(data);

}

refcountedstruct , REF() , UNREF() użycie w kodzie

Zamiast GC… Zliczanie referencji

Zamiast GC… Zliczanie referencji

Łatwe w obsłudze

Zamiast GC… Zliczanie referencji

Łatwe w obsłudze Proste w implementacji

Zamiast GC… Zliczanie referencji

Łatwe w obsłudze Proste w implementacji

Nie obsługuje poprawnie struktur cyklicznych

Zamiast GC… Zliczanie referencji

Łatwe w obsłudze Proste w implementacji

Nie obsługuje poprawnie struktur cyklicznych Spowalnia przypisania

Zamiast GC… Zliczanie referencji

Łatwe w obsłudze Proste w implementacji

Nie obsługuje poprawnie struktur cyklicznych Spowalnia przypisania Wymaga ciągłego pamiętania o REF i UNREF

Zamiast GC… Zliczanie referencji

Łatwe w obsłudze Proste w implementacji

Nie obsługuje poprawnie struktur cyklicznych Spowalnia przypisania Wymaga ciągłego pamiętania o REF i UNREF A jak REF albo UNREF rzuci wyjątek...

Zamiast GC… Zliczanie referencji

Zamiast GC… Zliczanie referencji Strefy pamięci (obstack)

Zamiast GC… Zliczanie referencji Strefy pamięci (obstack)

struct obstack *global_pool;struct obstack *connection_pool;struct obstack *request_pool;int main(){

/* inicjalizacja */while(1){

wait_for_connection();while(more_requests_available()){

handle_request();obstack_free(request_pool, NULL);

}obstack_free(connection_pool, NULL);

}}

Zamiast GC… Zliczanie referencji Strefy pamięci (obstack)

Zamiast GC… Zliczanie referencji Strefy pamięci (obstack)

Łatwe w obsłudze

Zamiast GC… Zliczanie referencji Strefy pamięci (obstack)

Łatwe w obsłudze Szereg dostępnych implementacji

Zamiast GC… Zliczanie referencji Strefy pamięci (obstack)

Łatwe w obsłudze Szereg dostępnych implementacji Szybkie

Zamiast GC… Zliczanie referencji Strefy pamięci (obstack)

Łatwe w obsłudze Szereg dostępnych implementacji Szybkie

Hermetyczne

Zamiast GC… Zliczanie referencji Strefy pamięci (obstack)

Łatwe w obsłudze Szereg dostępnych implementacji Szybkie

Hermetyczne Problem w przypadku zmian w kodzie

Zamiast GC… Zliczanie referencji Strefy pamięci (obstack)

Łatwe w obsłudze Szereg dostępnych implementacji Szybkie

Hermetyczne Problem w przypadku zmian w kodzie A jak pomylisz pulę pamięci przy alokacji...

Konfrontacja

Przykład 1 – wyrażeniaVector v1, v2, v3;Scalar s1, s2;

v3 = v1 * s1 + v2 * s2;

Konfrontacja

Przykład 1 – wyrażeniaVector v1, v2, v3;Scalar s1, s2;

v3 = v1 * s1 + v2 * s2;

Lub inaczej:v3 = v1.mult(s1).add(v2.mult(s2))

Konfrontacja

Przykład 1 – wyrażeniaVector v1, v2, v3;Scalar s1, s2;

v3 = v1 * s1 + v2 * s2;

Lub inaczej:v3 = v1.mult(s1).add(v2.mult(s2))

Ile obiektów będzie utworzonych?

Konfrontacja

Przykład 1 – wyrażeniaVector v1, v2, v3;Scalar s1, s2;

v3 = v1 * s1 + v2 * s2;

Lub inaczej:v3 = v1.mult(s1).add(v2.mult(s2))

Ile obiektów będzie utworzonych? Kto będzie sprzątał?

Konfrontacja

Przykład 2 – formatowanie

time_t tm;time(&tm);char *str = ctime(&tm);cout << str;delete str;

Kto sprząta?

Konfrontacja

Przykład 3 – zasoby zewnętrzne, GUI Problem: nie możemy samemu niszczyć obiektów Irytujący przykład: JFrame

JFrame frm = new JFrame();BigModel mdl = new BigModel();BigComponent cmp = new BigComponent(mdl);frm.add(cmp);frm.show();

Konfrontacja

Przykład 4 – wydajnośćclass A {

private int x; public A() { x = 0; ++x; }

}

class Example{

public static void Main() {

for (int i = 0; i < 500000000; ++i) { A a = new A(); }}

}

Konfrontacja

Wyniki dla linuxie (students)

Konfrontacja

Java:real 0m8.555suser 0m8.100ssys 0m0.350s

Konfrontacja

Java:real 0m8.555suser 0m8.100ssys 0m0.350s

Mono:real 0m2.907suser 0m2.690ssys 0m0.130s

Konfrontacja

Java:real 0m8.555suser 0m8.100ssys 0m0.350s

Mono:real 0m2.907suser 0m2.690ssys 0m0.130s

C++:real 0m5.320suser 0m4.360ssys 0m0.940s

Konfrontacja

A jak wyszło na Windows?

Konfrontacja

Java:Kernel: 0.015User: 0.156

.NET:Kernel: 0.031User: 0.109

C++:Kernel: 0.796User: 8.343

Konfrontacja

Przykład 5while (true){

Connection conn = GetConnection();ReadRequest(conn);SendResponse(conn);

}

Konfrontacja

Przykład 5while (true){

Connection conn = GetConnection();ReadRequest(conn);SendResponse(conn);

}

Pytanie: czy i kiedy połączenia same się będą zamykać?

Konfrontacja

Przykład 5while (true){

Connection conn = GetConnection();ReadRequest(conn);SendResponse(conn);

}

Pytanie: czy i kiedy połączenia same się będą zamykać? Odpowiedź: nie wiadomo czy i nie wiadomo kiedy

Konfrontacja

Koniec