Koncepcje programowania/Zarządzanie pamięcią

Z Wikibooks, biblioteki wolnych podręczników.
Przejdź do nawigacji Przejdź do wyszukiwania

Każde urządzenie komputerowe posiada jakąś pamięć. Każdy program gdzieś w tej pamięci musi być zapisany. Ponieważ ilość pamięci jest zawsze ograniczona, jednym z zadań programisty jest efektywne wykorzystanie tej przestrzeni.

Wyobraź sobie że massz 6 kwadratów, 6 bloków, 6 dostępnych komórek pamięci. Na razie wszystkie są puste. Jeśli gdzieś musimy zapisać jakąś informację, musimy wykorzystać w tym celu jakiś wolny blok pamięci. Wypełniamy więc go jakimś elementem, i mamy zajętą komorkę pamięci, coś do tego bloku zostało zapisane. Potem zapisujemy coś do kolenego bloku i kolejnego, aż w pewnym momencie wszystkie zostaną zajęte. Bardzo zła rzecz, ponieważ po ich zajęciu nie jesteśmy w stanie zapisać kolejnych informacji, nasz program w tym momencie może powodować wycieki pamięci albo nawet przestać działać.

Dlatego aby nie dochodzilo to takich incydentów, należy pamiętać by używać komórek pamięci tylko wtedy gdy są one potrzebne i kasować je, gdy potrzebne nie są, tak żebyśmy mogli w nim zapisywać kolejne dane w razie potrzeby.

Zasadniczo istnieją dwie metody zarządzania pamięcią. Pierwszy z nich już poznałeś w rozdziale o wskaźnikach. Jeśli czytałeś temat o wskaźnikach, wiesz już w jaki sposób się to robi, w sposób ręczny, programista na tu pełną kontrolę nad tym, ile jej użyć i w którym momencie ją zwolnić, musimy wprowadzać dodatkowy kod, który będzie za to odpowiedzialny. Przykład złego kodu w języku C++:

int function() {
  int* wsk = new int; // zarezerwowane pamięci na liczbę typu int
  *wsk = 20; // wpisanie w zarezerwowane miejsce wartości
  return *wsk;
}

W powyższym przykładzie wykonanie funkcji function spowoduje rezerwację obszaru pamięci na jedną liczbę typu int i zapisanie w nim wartości 20. Wartość ta jest zwracana przez funkcję, jednak obszar pamięci o adresie wskazywanym przez wskaźnik wsk nie zostaje zwolniony (brak wywołania instrukcji delete). Oznacza to wyciek pamięci – każde kolejne wywołanie funkcji function powiększy rozmiar tego wycieku co najmniej o rozmiar typu danych int.

Tej metody z reguły używamy gdzie jest istotna wysoka wydajność, żeby móc jak najwięcej wycisnąć z sprzętu.

Są też metody automatyczne, zwane z angielskiego garbage collector czyli Odśmiecanie pamięci, zbieranie nieużytków, automatyczna dealokacja. One są łatwiejsze, ponieważ język robi to za nas, my jako programiści w ogóle nie musimy się tym przejmować, my sobie tworzymy dowolne informmacje, zmienne w kodzie programu a garbage collector skasuje to, co według niego nie jest w tej chwilii potrzebne. Takie metoda, choć wygodna, z reguły jest mniej efektywna od standardowego, ręcznego zarzadzania pamięcią.

W zalezności od języka będzie się zaliczał do jednej bądź drugiej grupy. W przypadku c++ zaliczamy go oczywiście do pierwszej, Python z kolei zajmuje się tym w pełni automatycznie.