Web - Amazon

We provide Linux to the World


We support WINRAR [What is this] - [Download .exe file(s) for Windows]

CLASSICISTRANIERI HOME PAGE - YOUTUBE CHANNEL
SITEMAP
Audiobooks by Valerio Di Stefano: Single Download - Complete Download [TAR] [WIM] [ZIP] [RAR] - Alphabetical Download  [TAR] [WIM] [ZIP] [RAR] - Download Instructions

Make a donation: IBAN: IT36M0708677020000000008016 - BIC/SWIFT:  ICRAITRRU60 - VALERIO DI STEFANO or
Privacy Policy Cookie Policy Terms and Conditions
Wyciek pamięci - Wikipedia, wolna encyklopedia

Wyciek pamięci

Z Wikipedii

Wyciek pamięci (ang. memory leak) - utrata kontaktu z pewnym obszarem zarezerwowanej pamięci.

Kod programu, który powoduje wycieki pamięci, jest kodem błędnym.

Spis treści

[edytuj] Przykłady wycieków pamięci

[edytuj] C++

int main() {
  int a = 10;
  int* wsk = new int; // zarezerwowane pamięci na liczbę typu int
  *wsk = 20; // wpisanie w zarezerwowane miejsce wartości
  wsk = &a; // przypisanie wskaznikowi adres zmiennej a
  return 0;
}

Jak widać nastąpiła rezerwacja pamięci na liczbę typu int i została wpisana tam wartość 20. Następnie wskaźnikowi został przypisany adres zmiennej a, jednocześnie tracąc adres wcześniej zarezerwowanego obszaru pamięci. Od tej pory nie można już przywrócić wskazania na ten obszar, stąd też powstał wyciek pamięci.

[edytuj] C

#include <stdio.h>
#include <stdlib.h>
int main(void)
{
  void *p; /* Deklarujemy wskaznik do obszaru pamieci */
  p = malloc(50); /* Rezerwujemy 50 bajtow pod tym wskaznikiem */
  p = malloc(50); /* Rezerwujemy kolejne 50 bajtow */
  free(p); /* Zwalniamy pamiec, ale tylko jedne 50 bajtow */
  return 0;
}

W tym przypadku zwolnieniu uległo tylko 50 bajtów, reszta dalej jest używana przez program.

[edytuj] Java, C#

W takich językach programowania jak Java czy C# problem wycieków pamięci został częściowo zniwelowany poprzez zastosowanie odśmiecania pamięci lub inaczej śmieciarza (ang. Garbage Collector). Garbage Collector nie rozwiązuje jednak - jak wspomniano - całkowicie problemu z wyciekami pamięci, ponieważ zwalnia tylko pamięć, do której nie istnieją odwołania. Powoduje to, że niestarannie napisany kod może skutkować, iż śmieciarz nie zwolni pewnego obszaru pamięci, mimo, że nie zamierzamy go używać.

Prostym przykładem może być utworzenie przez programistę listy otwartych i listy już zamkniętych okienek (ArrayList openedWindows oraz ArrayList closedWindows). Jeśli po zamknięciu każdego okienka będziemy wrzucali je do listy closedWindows, to collector nigdy nie zwolni zajmowanej przez nie pamięci, mimo iż tak naprawdę będzie nam zależało na tylko kilku informacjach związanych z zamkniętym już okienkiem, np. jego tytule oraz jakimś identyfikatorze, które zajmują wiele mniej miejsca niż całe okienko. Rozwiązaniem jest wrzucanie do listy closedWindows instancji jakiejś prostej klasy zawierającej pola reprezentujące te dwie wspomniane informacje o okienku, tak aby nie trzymać referencji do całego okna.

[edytuj] Obsługa wyjątków a wycieki pamięci

Częstą sytuacją podczas działania programu jest zaalokowanie pewnego obszaru pamięci, pracy z nim a następnie zwolnienie go. W C++ taka funkcja mogłaby mieć postać (pominięto definicje klas i funkcji - nie są potrzebne w przykładzie):

class KlasaZasobu {
  // definicja klasy
};

void pracaZzasobem( KlasaZasobu* dana ) {
//   implementacja funkcji
}

void funkcja() { 
  KlasaZasobu* zasob = new KlasaZasobu(); // 1
  pracaZzasobem( zasob );                 // 2
  delete zasob;                           // 3
}

W (1) następuje zaalokowanie pamięci poprzez stworzenie obiektu KlasaZasobu. Następnie zostaje wywołana pewna funkcja pracaZzasobem( KlasaZasobu* ) (2) pracująca z obiektem klasy KlasaZasobu. Po tym wszystkim nastąpi zwolnienie zarezerwowanego obszaru pamięci w (3). Na pierwszy rzut oka, funkcja ta nie powoduje wycieków pamięci. Wyobraźmy sobie sytuację w której po zaalokowaniu pamięci w (1), funkcja pracaZzasobem( KlasaZasobu* ) wyrzuci wyjątek (np. z powodu błędnych danych). Zostaną usunięte wszystkie obiekty lokalne i wykonanie programu zostanie przekazane do miejsca gdzie została wywołana funkcja funkcja() - zgodnie z działaniem mechanizmu wyjątków. Lokalnym obiektem w tym przypadku jest wskaźnik zasob i zostanie on usunięty, jednak zarezerwowany obszar pamięci do którego ma dostęp już nie. Z powodu wyrzucenia wyjątku przez funkcję pracaZzasobem( KlasaZasobu* ), zasób nie zostanie zwolniony w (3). W efekcie powstanie wyciek pamięci.

Aby zaradzić takiej sytuacji i obronić się przed wyciekiem pamięci stosuje się dodatkową klasę, w której w konstruktorze przypisuje się alokowany wskaźnik a w destruktorze zwalnia się zaalokowany obszar pamięci:

class KlasaZasobu {
  // definicja klasy
};

void pracaZzasobem( KlasaZasobu* dana ) {
//   implementacja funkcji
}

class KlasaPomocnicza {
  public:
    KlasaPomocnicza( KlasaZasobu* wskaznik ) {
      this->dana = wskaznik;
    }
    KlasaZasobu* pobierzWskaznik() {
      return this->dana;
    }
    ~KlasaPomocnicza() {
      delete this->dana;
    }
 pivate:
   KlasaZasobu* dana;
};

void funkcja() { 
  KlasaPomocnicza zasob( new KlasaZasobu() ); // 1
  pracaZzasobem( zasob.pobierzWskaznik() );   // 2
}

W (1) następuje stworzenie lokalnego obiektu klasy KlasaPomocnicza i podanie w konstruktorze wskaźnika do nowozaalokowanego obszaru pamięci. Konstruktor ten przypisuje polu dana wskaźnik nowozaalokowanego obszaru. Następnie zostaje wywołana funkcja pracaZzasobem( KlasaZasobu* ) której jako parametr podajemy wskaźnik korzystając z funkcji w klasie KlasaPomocnicza. Gdy funkcja pracaZzasobem( KlasaZsobu* ) wyrzuci wyjątek zostaną usunięte wszystkie obiekty lokalne. W tym wypadku obiektem lokalnym jest obiekt zasob dla którego zostanie wywołany jego destruktor w którym nastąpi zwolnienie zaalokowanego zasobu. Funkcja nie będzie mieć również wycieku pamięci w momencie gdy funkcja pracaZzasobem( KlasaZasobu* ) nie wyrzuci wyjątku ponieważ również skończy się zasięg ważności obiektu zasob i zostanie on również usunięty (a wraz z nim zwolniony zostanie zaalokowany obszar pamięci).

Programista nie musi pisać takiej klasy pomocniczej dla klasy której obiekt alokuje używając operatora new. Z pomocą przychodzą szablony klas. W standardowej bibliotece klas jest to szablon auto_ptr. Dostępne są również inne implementacje. Najpopularniejszą są szablony z biblioteki Boost: scoped_ptr (dla prostego zwalniania obiektów w danym zasięgu ważności) oraz shared_ptr (dla automatycznego zwalniania współdzielonych zasobów poza zasięgiem ważności).

Problem wycieków pamięci w związku z obsługą wyjątków dotyczy głównie C++. W innych językach problem ten nie występuje ze względu na brak mechanizmu wyjątków lub inną politykę zarządzania pamięcią (Garbage collection).

[edytuj] Skutki

Wycieki pamięci są efektem bardzo niepożądanym. Program bowiem zajmuje coraz większe zasoby, ale nie jest w stanie ich wykorzystać ani zwolnić. Szczególnie w aplikacjach, które działają przez długi czas (w większości serwerowych), efekt wycieku pamięci stopniowo narasta. Sam wyciek prowadzi do spadku wydajności, w skrajnym przypadku zawieszenia się programu, a nawet zablokowania całego systemu. Doprowadzenie w wadliwym programie do możliwie dużego wycieku pamięci może być jednym ze sposobów wykonania ataku DoS.

[edytuj] Zobacz też

Our "Network":

Project Gutenberg
https://gutenberg.classicistranieri.com

Encyclopaedia Britannica 1911
https://encyclopaediabritannica.classicistranieri.com

Librivox Audiobooks
https://librivox.classicistranieri.com

Linux Distributions
https://old.classicistranieri.com

Magnatune (MP3 Music)
https://magnatune.classicistranieri.com

Static Wikipedia (June 2008)
https://wikipedia.classicistranieri.com

Static Wikipedia (March 2008)
https://wikipedia2007.classicistranieri.com/mar2008/

Static Wikipedia (2007)
https://wikipedia2007.classicistranieri.com

Static Wikipedia (2006)
https://wikipedia2006.classicistranieri.com

Liber Liber
https://liberliber.classicistranieri.com

ZIM Files for Kiwix
https://zim.classicistranieri.com


Other Websites:

Bach - Goldberg Variations
https://www.goldbergvariations.org

Lazarillo de Tormes
https://www.lazarillodetormes.org

Madame Bovary
https://www.madamebovary.org

Il Fu Mattia Pascal
https://www.mattiapascal.it

The Voice in the Desert
https://www.thevoiceinthedesert.org

Confessione d'un amore fascista
https://www.amorefascista.it

Malinverno
https://www.malinverno.org

Debito formativo
https://www.debitoformativo.it

Adina Spire
https://www.adinaspire.com