logo

Alokacja pamięci stosu i sterty

Pamięć w programie C/C++/Java może być alokowana na stosie lub stercie.
Warunek wstępny: Układ pamięci programu C .


Alokacja stosu: Alokacja odbywa się w sąsiadujących blokach pamięci. Nazywamy to alokacją pamięci stosu, ponieważ alokacja odbywa się na stosie wywołań funkcji. Rozmiar alokowanej pamięci jest znany kompilatorowi i za każdym razem, gdy wywoływana jest funkcja, jej zmiennym zostaje przydzielona pamięć na stosie. Za każdym razem, gdy wywołanie funkcji się zakończy, pamięć na zmienne zostaje zwolniona. Wszystko to dzieje się przy użyciu predefiniowanych procedur w kompilatorze. Programista nie musi się martwić o alokację pamięci i cofanie alokacji zmiennych stosu. Ten rodzaj alokacji pamięci jest również nazywany alokacją pamięci tymczasowej, ponieważ gdy tylko metoda zakończy wykonywanie, wszystkie dane należące do tej metody zostaną automatycznie usunięte ze stosu. Oznacza to, że dowolna wartość przechowywana w schemacie pamięci stosu jest dostępna, dopóki metoda nie zakończyła wykonywania i jest aktualnie uruchomiona.



komunikacja analogowa

Kluczowe punkty:

  • Jest to schemat tymczasowej alokacji pamięci, w którym elementy danych są dostępne tylko wtedy, gdy aktualnie działa metoda (), która je zawierała.
  • Przydziela lub zwalnia pamięć automatycznie, gdy tylko odpowiednia metoda zakończy wykonywanie.
  • Otrzymujemy odpowiedni błąd Java. język. Błąd StackOverFlow przez JVM , Jeśli pamięć stosu jest całkowicie zapełniona.
  • Alokacja pamięci stosu jest uważana za bezpieczniejszą w porównaniu z alokacją pamięci sterty, ponieważ dostęp do przechowywanych danych może uzyskać wyłącznie wątek właściciela.
  • Alokacja i dealokacja pamięci są szybsze w porównaniu do alokacji pamięci sterty.
  • Pamięć stosowa ma mniej miejsca w porównaniu do pamięci stertowej.
C++
int main() {  // All these variables get memory  // allocated on stack  int a;  int b[10];  int n = 20;  int c[n]; }>


Alokacja sterty: Pamięć jest przydzielana podczas wykonywania instrukcji napisanych przez programistów. Zauważ, że nazwa sterty nie ma nic wspólnego z wyciek pamięci może się zdarzyć w programie.



Alokacja pamięci sterty jest dalej podzielona na trzy kategorie: - Te trzy kategorie pomagają nam ustalić priorytety danych (obiektów), które mają być przechowywane w pamięci sterty lub w Zbieranie śmieci .

ciąg Java na znak
  • Młoda generacjA - Jest to część pamięci, w której tworzone są wszystkie nowe dane (obiekty) w celu przydzielenia miejsca i za każdym razem, gdy ta pamięć zostanie całkowicie zapełniona, reszta danych jest przechowywana w koszu.
  • Stare lub stałe pokolenie – Jest to część pamięci sterty, która zawiera starsze obiekty danych, które nie są często używane lub w ogóle nie są używane.
  • Stałe wytwarzanie – Jest to część pamięci sterty, która zawiera metadane maszyny JVM dla klas wykonawczych i metod aplikacji.

Kluczowe punkty:

  • Otrzymujemy odpowiedni komunikat o błędzie, jeśli przestrzeń sterty jest całkowicie zapełniona, Jawa. lang.OutOfMemoryError przez JVM.
  • Ten schemat alokacji pamięci różni się od alokacji przestrzeni stosu, w tym przypadku nie jest dostępna funkcja automatycznego zwalniania alokacji. Musimy użyć modułu zbierającego śmieci, aby usunąć stare, nieużywane obiekty, aby efektywnie wykorzystać pamięć.
  • Czas przetwarzania (czas dostępu) tej pamięci jest dość powolny w porównaniu do pamięci stosu.
  • Pamięć sterty nie jest również tak bezpieczna dla wątków jak pamięć stosu, ponieważ dane przechowywane w pamięci sterty są widoczne dla wszystkich wątków.
  • Rozmiar pamięci sterty jest znacznie większy w porównaniu do pamięci stosu.
  • Pamięć sterty jest dostępna lub istnieje tak długo, jak działa cała aplikacja (lub program Java).
CPP
int main() {  // This memory for 10 integers  // is allocated on heap.  int *ptr = new int[10]; }>

Mieszany przykład obu rodzajów alokacji pamięci Heap i Stack w Javie:



C++
#include  using namespace std; int main() {  int a = 10; // stored in stack  int* p = new int(); // allocate memory in heap  *p = 10;  delete (p);  p = new int[4]; // array in heap allocation  delete[] p;  p = NULL; // free heap  return 0; }>
Jawa
class Emp {  int id;  String emp_name;  public Emp(int id, String emp_name) {  this.id = id;  this.emp_name = emp_name;  } } public class Emp_detail {  private static Emp Emp_detail(int id, String emp_name) {  return new Emp(id, emp_name);  }  public static void main(String[] args) {  int id = 21;  String name = 'Maddy';  Emp person_ = null;  person_ = Emp_detail(id, name);  } }>
Pyton
def main(): a = 10 # stored in stack p = None # declaring p variable p = 10 # allocating memory in heap del p # deleting memory allocation in heap p = [None] * 4 # array in heap allocation p = None # free heap return 0 if __name__ == '__main__': main()>
JavaScript
// Define the Emp class with id and emp_name properties class Emp {  constructor(id, emp_name) {  this.id = id; // Initialize id  this.emp_name = emp_name; // Initialize emp_name  } } // Create an instance of the Emp class const person = new Emp(21, 'Maddy'); // Initialize person with id 21 and emp_name 'Maddy' console.log(person); // Output the person object to the console>

Oto wnioski, jakie wyciągniemy po analizie powyższego przykładu:

string w porównaniu do Java
  • Gdy rozpoczynamy wykonywanie programu have, wszystkie klasy wykonawcze są przechowywane w przestrzeni pamięci sterty.
  • Następnie w następnej linii znajdujemy metodę main(), która jest przechowywana na stosie wraz ze wszystkimi jej metodami pierwotnymi (lub lokalnymi), a zmienna referencyjna Emp typu Emp_detail również będzie przechowywana na stosie i wskaże odpowiedni obiekt przechowywane w pamięci sterty.
  • Następnie następna linia wywoła sparametryzowany konstruktor Emp(int, String) z funkcji main() i również przydzieli dane na górze tego samego bloku pamięci stosu. To będzie przechowywać:
    • Odwołanie do obiektu wywołanego obiektu pamięci stosu.
    • Wartość pierwotna ( Zmienna referencyjna argumentu String nazwa_emp będzie wskazywać rzeczywisty ciąg znaków z puli ciągów do pamięci sterty.
  • Następnie metoda główna ponownie wywoła metodę statyczną Emp_detail(), dla której alokacja zostanie dokonana w bloku pamięci stosu na wierzchu poprzedniego bloku pamięci.
  • Zmienna referencyjna argumentu String nazwa_emp będzie wskazywać rzeczywisty ciąg znaków z puli ciągów do pamięci sterty.
  • Zatem dla nowo utworzonego obiektu Emp typu Emp_detail i wszystkie zmienne instancji będą przechowywane w pamięci sterty.
  • Zmienna referencyjna argumentu String nazwa_emp będzie wskazywać rzeczywisty ciąg znaków z puli ciągów do pamięci sterty.

  • Przedstawienie obrazowe, jak pokazano na rysunku 1 poniżej:

    Zmienna referencyjna argumentu String nazwa_emp będzie wskazywać rzeczywisty ciąg znaków z puli ciągów do pamięci sterty.
  • Ryc.1

    Kluczowe różnice między alokacją stosu i sterty

    1. Na stosie alokacja i dealokacja są wykonywane automatycznie przez kompilator, podczas gdy na stercie musi to zrobić programista ręcznie.
    2. Obsługa ramki sterty jest droższa niż obsługa ramki stosu.
    3. Problem niedoboru pamięci częściej występuje na stosie, podczas gdy głównym problemem w pamięci sterty jest fragmentacja.
    4. Dostęp do ramki stosu jest łatwiejszy niż do ramki sterty, ponieważ stos ma mały obszar pamięci i jest przyjazny dla pamięci podręcznej, ale w przypadku ramek sterty, które są rozproszone w pamięci, powoduje to więcej braków pamięci podręcznej.
    5. Stos nie jest elastyczny, rozmiaru przydzielonej pamięci nie można zmienić, podczas gdy sterta jest elastyczna i przydzieloną pamięć można zmieniać.
    6. Dostęp do czasu sterty zajmuje więcej niż stos.

    Wykres porównania

    ParametrSTOSSTERTA
    PodstawowyPamięć jest alokowana w ciągłym bloku.Pamięć jest przydzielana w dowolnej losowej kolejności.
    Alokacja i de-alokacjaAutomatycznie według instrukcji kompilatora.Instrukcja przez programistę.
    KosztMniejWięcej
    RealizacjaŁatwyTwardy
    Czas dostępuSzybciejWolniej
    Główna kwestiaNiedobór pamięciFragmentacja pamięci
    Miejscowość odniesieniaDoskonałyOdpowiedni
    BezpieczeństwoBezpieczne wątki, dostęp do przechowywanych danych może uzyskać tylko właścicielNie jest bezpieczny dla wątków, przechowywane dane są widoczne dla wszystkich wątków
    ElastycznośćStały rozmiarZmiana rozmiaru jest możliwa
    Struktura typu danychLiniowyHierarchiczny
    PreferowaneW tablicy preferowana jest statyczna alokacja pamięci.Na połączonej liście preferowana jest alokacja pamięci sterty.
    RozmiarPamięć mała niż sterta.Większa niż pamięć stosu.