109
Zarządzanie pamięcią: ręczne czy automatyczne Łukasz Kosson Tomasz Wasersztrum

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

  • Upload
    carlyn

  • View
    74

  • Download
    0

Embed Size (px)

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

Citation preview

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

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

Łukasz Kosson

Tomasz Wasersztrum

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

Podstawy

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

Podstawy

Stos i sterta

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

Podstawy

Stos i sterta

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

Podstawy

Stos i sterta malloc() i free()

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

Podstawy

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

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

Podstawy

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

tablica wolnych bloków

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

Podstawy

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

tablica wolnych bloków bloki „zawieszone”

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

Podstawy

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

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

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

Podstawy

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

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

new i delete

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

Problemy zarządzania pamięcią

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

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

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

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

Pseudokod obsługi windy.

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

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

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

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

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

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

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

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

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

Garbage collector

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

Garbage collector

Czym jest i co robi?

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

Garbage collector

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

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

Garbage collector

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

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

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

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

Garbage collector

Czym nie jest i czego nie robi?

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

Garbage collector

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

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

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

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

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

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

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

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

Garbage collector

Gdzie jest wykorzystywany?

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

Garbage collector

Gdzie jest wykorzystywany? Początki: LISP, 1960

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

Garbage collector

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

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

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

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

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)

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

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

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

GC – zasada działania

Jakie obiekty sprzątać?

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

GC – zasada działania

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

semantycznie

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

GC – zasada działania

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

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

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

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

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

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

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

GC – zasada działania

Algorytm naiwny (mark and sweep):

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

GC – zasada działania

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

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

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

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

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ść

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

GC – zasada działania

Wady algorytmu naiwnego:

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

GC – zasada działania

Wady algorytmu naiwnego: Wymaga wstrzymania procesu

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

GC – zasada działania

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

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

GC – zasada działania

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

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

GC – zasada działania

Modyfikacje algorytmu mark-and-sweep:

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

GC – zasada działania

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

wymagania pamięciowe

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

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ę

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

GC – zasada działania

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

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

GC – zasada działania

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

Wniosek: Nie traktować wszystkich obiektów jednakowo

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

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

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

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

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

GC – zasada działania

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

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

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

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

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)

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

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

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

GC – jak mu pomóc

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

GC – jak mu pomóc

Weak reference:

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

GC – jak mu pomóc

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

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

GC – jak mu pomóc

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

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

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

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

GC – jak sobie pomóc

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

GC – jak sobie pomóc

Finalizacja:

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

GC – jak sobie pomóc

Finalizacja: Mechanizm zastępujący destruktory

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

GC – jak sobie pomóc

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

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

GC – jak sobie pomóc

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

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

GC – środowiska hybrydowe

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

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

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);

}

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

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){ ...}

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

Zamiast GC…

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

Zamiast GC… Zliczanie referencji

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

Zamiast GC…

refcountedstruct , REF() , UNREF()

Zliczanie referencji

struct refcountedstruct { int refcount;}

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

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

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()

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

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

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

Zamiast GC… Zliczanie referencji

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

Zamiast GC… Zliczanie referencji

Łatwe w obsłudze

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

Zamiast GC… Zliczanie referencji

Łatwe w obsłudze Proste w implementacji

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

Zamiast GC… Zliczanie referencji

Łatwe w obsłudze Proste w implementacji

Nie obsługuje poprawnie struktur cyklicznych

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

Zamiast GC… Zliczanie referencji

Łatwe w obsłudze Proste w implementacji

Nie obsługuje poprawnie struktur cyklicznych Spowalnia przypisania

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

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

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

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...

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

Zamiast GC… Zliczanie referencji

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

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

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

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);

}}

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

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

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

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

Łatwe w obsłudze

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

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

Łatwe w obsłudze Szereg dostępnych implementacji

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

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

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

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

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

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

Hermetyczne

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

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

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

Hermetyczne Problem w przypadku zmian w kodzie

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

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...

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

Konfrontacja

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

v3 = v1 * s1 + v2 * s2;

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

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))

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

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?

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

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ł?

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

Konfrontacja

Przykład 2 – formatowanie

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

Kto sprząta?

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

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();

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

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(); }}

}

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

Konfrontacja

Wyniki dla linuxie (students)

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

Konfrontacja

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

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

Konfrontacja

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

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

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

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

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

Konfrontacja

A jak wyszło na Windows?

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

Konfrontacja

Java:Kernel: 0.015User: 0.156

.NET:Kernel: 0.031User: 0.109

C++:Kernel: 0.796User: 8.343

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

Konfrontacja

Przykład 5while (true){

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

}

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

Konfrontacja

Przykład 5while (true){

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

}

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

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

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

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

Konfrontacja

Koniec