it-swarm-id.com

Apa dan di mana tumpukan dan tumpukan itu?

Buku bahasa pemrograman menjelaskan bahwa tipe nilai dibuat pada stack , dan tipe referensi dibuat pada heap , tanpa menjelaskan apa kedua hal ini. Saya belum membaca penjelasan yang jelas tentang ini. Saya mengerti apa stack. Tapi, 

  • di mana dan apa mereka (secara fisik dalam memori komputer nyata)?
  • Sejauh mana mereka dikendalikan oleh runtime OS atau bahasa?
  • Apa ruang lingkup mereka?
  • Apa yang menentukan ukuran masing-masing?
  • Apa yang membuat seseorang lebih cepat? 
7473
mattshane

Tumpukan adalah memori yang disisihkan sebagai ruang awal untuk utas eksekusi. Ketika suatu fungsi dipanggil, sebuah blok dicadangkan di atas tumpukan untuk variabel lokal dan beberapa data pembukuan. Ketika fungsi itu kembali, blok menjadi tidak digunakan dan dapat digunakan saat suatu fungsi dipanggil. Tumpukan selalu dipesan dalam urutan LIFO (terakhir masuk pertama keluar); blok yang paling baru dipesan selalu blok berikutnya yang akan dibebaskan. Ini membuatnya sangat sederhana untuk melacak tumpukan; membebaskan blok dari tumpukan tidak lebih dari menyesuaikan satu pointer.

Heap adalah memori yang disisihkan untuk alokasi dinamis. Berbeda dengan stack, tidak ada pola yang dipaksakan untuk alokasi dan deallokasi blok dari heap; Anda dapat mengalokasikan blok kapan saja dan membebaskannya kapan saja. Ini membuatnya jauh lebih kompleks untuk melacak bagian mana dari tumpukan yang dialokasikan atau gratis pada waktu tertentu; ada banyak pengalokasi tumpukan kustom yang tersedia untuk menyesuaikan kinerja tumpukan untuk berbagai pola penggunaan.

Setiap utas mendapat tumpukan, sementara biasanya hanya ada satu tumpukan untuk aplikasi (meskipun tidak jarang memiliki banyak tumpukan untuk berbagai jenis alokasi).

Untuk menjawab pertanyaan Anda secara langsung: 

Sejauh mana mereka dikendalikan oleh runtime OS atau bahasa?

OS mengalokasikan tumpukan untuk setiap utas tingkat sistem saat utas dibuat. Biasanya OS dipanggil oleh runtime bahasa untuk mengalokasikan heap untuk aplikasi.

Apa ruang lingkup mereka?

Tumpukan dilampirkan ke utas, jadi ketika utas keluar, tumpukan diambil kembali. Tumpukan biasanya dialokasikan pada startup aplikasi oleh runtime, dan direklamasi ketika aplikasi (secara teknis memproses) keluar.

Apa yang menentukan ukuran masing-masing? 

Ukuran tumpukan diatur saat utas dibuat. Ukuran heap diatur pada startup aplikasi, tetapi dapat tumbuh sesuai ruang yang dibutuhkan (pengalokasi meminta lebih banyak memori dari sistem operasi).

Apa yang membuatnya lebih cepat?

Tumpukan lebih cepat karena pola akses membuatnya sepele untuk mengalokasikan dan membatalkan alokasi memori dari itu (pointer/integer hanya bertambah atau berkurang), sementara tumpukan memiliki pembukuan yang jauh lebih kompleks yang terlibat dalam alokasi atau deallokasi. Selain itu, setiap byte dalam tumpukan cenderung digunakan kembali sangat sering yang artinya cenderung dipetakan ke cache prosesor, membuatnya sangat cepat. Hit kinerja lain untuk heap adalah heap, yang sebagian besar merupakan sumber daya global, biasanya harus multi-threading aman, yaitu setiap alokasi dan deallokasi harus - biasanya - disinkronkan dengan "semua" akses tumpukan lainnya dalam program.

Demonstrasi yang jelas:
Sumber gambar: vikashazrati.wordpress.com

5529
Jeff Hill

Stack:

  • Disimpan di komputer RAM sama seperti heap.
  • Variabel yang dibuat pada stack akan keluar dari ruang lingkup dan secara otomatis dialokasikan.
  • Jauh lebih cepat untuk mengalokasikan dibandingkan dengan variabel di heap.
  • Diimplementasikan dengan struktur data tumpukan yang sebenarnya.
  • Menyimpan data lokal, mengembalikan alamat, digunakan untuk melewati parameter.
  • Dapat memiliki stack overflow ketika terlalu banyak stack digunakan (kebanyakan dari rekursi tak terbatas atau terlalu dalam, alokasi yang sangat besar).
  • Data yang dibuat pada stack dapat digunakan tanpa pointer.
  • Anda akan menggunakan tumpukan jika Anda tahu persis berapa banyak data yang perlu Anda alokasikan sebelum waktu kompilasi dan itu tidak terlalu besar.
  • Biasanya ukuran maksimum sudah ditentukan saat program Anda mulai.

Tumpukan:

  • Disimpan di komputer RAM sama seperti tumpukan.
  • Dalam C++, variabel pada heap harus dihancurkan secara manual dan tidak pernah keluar dari ruang lingkup. Data dibebaskan dengan delete, delete[], atau free.
  • Lebih lambat untuk mengalokasikan dibandingkan dengan variabel pada stack.
  • Digunakan sesuai permintaan untuk mengalokasikan blok data untuk digunakan oleh program.
  • Dapat mengalami fragmentasi ketika ada banyak alokasi dan deallokasi.
  • Dalam C++ atau C, data yang dibuat pada heap akan ditunjukkan oleh pointer dan dialokasikan dengan new atau malloc.
  • Dapat mengalami kegagalan alokasi jika buffer yang terlalu besar diminta untuk dialokasikan.
  • Anda akan menggunakan heap jika Anda tidak tahu persis berapa banyak data yang akan Anda butuhkan pada saat dijalankan atau jika Anda perlu mengalokasikan banyak data.
  • Bertanggung jawab atas kebocoran memori.

Contoh:

int foo()
{
  char *pBuffer; //<--nothing allocated yet (excluding the pointer itself, which is allocated here on the stack).
  bool b = true; // Allocated on the stack.
  if(b)
  {
    //Create 500 bytes on the stack
    char buffer[500];

    //Create 500 bytes on the heap
    pBuffer = new char[500];

   }//<-- buffer is deallocated here, pBuffer is not
}//<--- oops there's a memory leak, I should have called delete[] pBuffer;
2199
Brian R. Bondy

Poin yang paling penting adalah bahwa tumpukan dan tumpukan adalah istilah umum untuk cara di mana memori dapat dialokasikan. Mereka dapat diimplementasikan dalam banyak cara yang berbeda, dan istilah ini berlaku untuk konsep dasar.

  • Dalam tumpukan item, item duduk satu di atas yang lain dalam urutan mereka ditempatkan di sana, dan Anda hanya dapat menghapus yang atas (tanpa menjatuhkan semuanya).

    Stack like a stack of papers

    Kesederhanaan tumpukan adalah bahwa Anda tidak perlu mempertahankan tabel yang berisi catatan setiap bagian dari memori yang dialokasikan; satu-satunya informasi negara yang Anda butuhkan adalah satu penunjuk ke ujung tumpukan. Untuk mengalokasikan dan menghapus alokasi, Anda hanya menambah dan mengurangi pointer tunggal itu. Catatan: tumpukan kadang-kadang dapat diimplementasikan untuk memulai di bagian atas dari memori dan memperluas ke bawah daripada tumbuh ke atas.

  • Dalam tumpukan, tidak ada urutan khusus untuk cara item ditempatkan. Anda dapat menjangkau dan menghapus item dalam urutan apa pun karena tidak ada item 'teratas' yang jelas.

    Heap like a heap of licorice allsorts

    Alokasi tumpukan memerlukan penyimpanan catatan penuh dari memori yang dialokasikan dan apa yang tidak, serta beberapa pemeliharaan overhead untuk mengurangi fragmentasi, menemukan segmen memori yang berdekatan cukup besar agar sesuai dengan ukuran yang diminta, dan sebagainya. Memori dapat di-de-alokasi kapan saja sehingga menyisakan ruang kosong. Kadang-kadang pengalokasi memori akan melakukan tugas-tugas perawatan seperti mendefrag memori dengan memindahkan memori yang dialokasikan, atau mengumpulkan sampah - mengidentifikasi saat runtime ketika memori tidak lagi dalam ruang lingkup dan membatalkan alokasi. 

Gambar-gambar ini harus melakukan pekerjaan yang cukup baik untuk menggambarkan dua cara mengalokasikan dan membebaskan memori dalam tumpukan dan tumpukan. Yum!

  • Sejauh mana mereka dikendalikan oleh runtime OS atau bahasa?

    Seperti disebutkan, heap dan stack adalah istilah umum, dan dapat diimplementasikan dengan banyak cara. Program komputer biasanya memiliki tumpukan yang disebut tumpukan - panggilan yang menyimpan informasi yang relevan dengan fungsi saat ini seperti pointer ke mana fungsi itu dipanggil dari, dan variabel lokal apa pun. Karena fungsi memanggil fungsi lain dan kemudian kembali, tumpukan tumbuh dan menyusut untuk menyimpan informasi dari fungsi lebih jauh ke tumpukan panggilan. Suatu program tidak benar-benar memiliki kontrol runtime atasnya; itu ditentukan oleh bahasa pemrograman, OS dan bahkan arsitektur sistem.

    Heap adalah istilah umum yang digunakan untuk setiap memori yang dialokasikan secara dinamis dan acak; mis. rusak. Memori biasanya dialokasikan oleh OS, dengan aplikasi yang memanggil fungsi API untuk melakukan alokasi ini. Ada sedikit overhead yang diperlukan dalam mengelola memori yang dialokasikan secara dinamis, yang biasanya ditangani oleh OS.

  • Apa ruang lingkup mereka?

    Tumpukan panggilan adalah konsep tingkat rendah sehingga tidak berhubungan dengan 'ruang lingkup' dalam arti pemrograman. Jika Anda membongkar beberapa kode, Anda akan melihat referensi gaya pointer relatif ke bagian-bagian stack, tetapi sejauh menyangkut bahasa tingkat yang lebih tinggi, bahasa tersebut memberlakukan aturan cakupannya sendiri. Namun, satu aspek penting dari tumpukan adalah bahwa begitu suatu fungsi kembali, segala sesuatu yang bersifat lokal dari fungsi itu segera dibebaskan dari tumpukan itu. Itu bekerja dengan cara yang Anda harapkan akan berfungsi mengingat cara kerja bahasa pemrograman Anda. Dalam tumpukan, itu juga sulit untuk didefinisikan. Cakupannya adalah apa pun yang diekspos oleh OS, tetapi bahasa pemrograman Anda mungkin menambahkan aturannya tentang apa "lingkup" dalam aplikasi Anda. Arsitektur prosesor dan OS menggunakan pengalamatan virtual, yang diterjemahkan oleh prosesor ke alamat fisik dan ada kesalahan halaman, dll. Mereka melacak halaman apa yang termasuk dalam aplikasi mana. Anda tidak pernah benar-benar perlu khawatir tentang ini, karena Anda hanya menggunakan metode apa pun yang digunakan bahasa pemrograman Anda untuk mengalokasikan dan mengosongkan memori, dan memeriksa kesalahan (jika alokasi/pembebasan gagal karena alasan apa pun).

  • Apa yang menentukan ukuran masing-masing?

    Sekali lagi, itu tergantung pada bahasa, kompiler, sistem operasi dan arsitektur. Tumpukan biasanya pra-dialokasikan, karena menurut definisi itu harus memori yang berdekatan (lebih banyak pada paragraf terakhir). Kompilator bahasa atau OS menentukan ukurannya. Anda tidak menyimpan potongan besar data di stack, jadi itu akan cukup besar sehingga tidak boleh sepenuhnya digunakan, kecuali dalam kasus rekursi tak berujung yang tidak diinginkan (karenanya, "stack overflow") atau keputusan pemrograman tidak biasa lainnya.

    Tumpukan adalah istilah umum untuk apa pun yang dapat dialokasikan secara dinamis. Tergantung pada cara Anda melihatnya, ukurannya terus berubah. Dalam prosesor dan sistem operasi modern cara tepatnya cara kerjanya sangat abstrak, jadi Anda biasanya tidak perlu terlalu khawatir tentang cara kerjanya jauh di bawah, kecuali bahwa (dalam bahasa yang memungkinkan Anda), Anda tidak boleh menggunakan memori yang Anda belum mengalokasikan atau memori yang telah Anda bebaskan.Apa yang membuat seseorang lebih cepat?.

  • What makes one faster?

    The stack is faster because all free memory is always contiguous. No list needs to be maintained of all the segments of free memory, just a single pointer to the current top of the stack. Compilers usually store this pointer in a special, fast register for this purpose. What's more, subsequent operations on a stack are usually concentrated within very nearby areas of memory, which at a very low level is good for optimization by the processor on-die caches.

1305
thomasrutter

(Saya telah memindahkan jawaban ini dari pertanyaan lain yang kurang lebih merupakan jawaban dari pertanyaan ini.)

Jawaban untuk pertanyaan Anda adalah implementasi spesifik dan dapat bervariasi di antara kompiler dan arsitektur prosesor. Namun, inilah penjelasan yang disederhanakan.

  • Baik stack dan heap adalah area memori yang dialokasikan dari sistem operasi yang mendasarinya (seringkali memori virtual yang dipetakan ke memori fisik sesuai permintaan).
  • Dalam lingkungan multi-utas, masing-masing utas akan memiliki tumpukan mandiri sepenuhnya tetapi mereka akan berbagi tumpukan. Akses bersamaan harus dikontrol di heap dan tidak mungkin di stack.

Tumpukan itu

  • Tumpukan berisi daftar tertaut blok yang digunakan dan gratis. Alokasi baru pada heap (oleh new atau malloc) dipenuhi dengan membuat blok yang sesuai dari salah satu blok gratis. Ini membutuhkan pembaruan daftar blok pada heap. Ini informasi meta tentang blok di heap juga disimpan di heap sering di area kecil tepat di depan setiap blok.
  • Seiring bertambahnya tumpukan, blok baru sering dialokasikan dari alamat yang lebih rendah ke alamat yang lebih tinggi. Dengan demikian Anda dapat menganggap tumpukan sebagai tumpukan dari blok memori yang tumbuh dalam ukuran sebagai memori dialokasikan. Jika tumpukan terlalu kecil untuk alokasi, ukuran seringkali dapat ditingkatkan dengan memperoleh lebih banyak memori dari sistem operasi yang mendasarinya.
  • Mengalokasikan dan menghilangkan blok banyak kecil dapat meninggalkan tumpukan dalam keadaan di mana ada banyak blok kecil gratis diselingi antara blok yang digunakan. Permintaan untuk mengalokasikan blok besar mungkin gagal karena tidak ada blok gratis yang cukup besar untuk memenuhi permintaan alokasi meskipun ukuran gabungan blok gratis mungkin cukup besar. Ini disebut heap fragmentasi .
  • Ketika blok bekas yang berdekatan dengan blok bebas dideallocated, blok bebas baru dapat digabungkan dengan blok bebas yang berdekatan untuk membuat blok bebas yang lebih besar secara efektif mengurangi fragmentasi tumpukan.

The heap

Tumpukan

  • Tumpukan sering bekerja dalam tandem dekat dengan register khusus pada CPU bernama stack pointer . Awalnya, penunjuk tumpukan mengarah ke bagian atas tumpukan (alamat tertinggi pada tumpukan).
  • CPU memiliki instruksi khusus untuk mendorong nilai ke stack dan popping mereka kembali dari stack. Setiap Push menyimpan nilai di lokasi saat ini dari penunjuk tumpukan dan mengurangi penunjuk tumpukan. A pop mengambil nilai yang ditunjuk oleh stack pointer dan kemudian meningkatkan stack pointer (jangan bingung dengan fakta bahwa menambahkan nilai ke stack berkurang stack pointer dan menghapus nilai meningkatkan itu. Ingat bahwa tumpukan tumbuh ke bawah). Nilai yang disimpan dan diambil adalah nilai register CPU.
  • Ketika suatu fungsi dipanggil CPU menggunakan instruksi khusus yang mendorong penunjuk instruksi saat ini , mis. Alamat kode yang dieksekusi pada stack. CPU kemudian melompat ke fungsi dengan mengatur penunjuk instruksi .__ ke alamat fungsi yang dipanggil. Kemudian, ketika fungsi kembali, penunjuk instruksi lama muncul dari tumpukan dan eksekusi dilanjutkan pada kode setelah panggilan ke fungsi.
  • Ketika suatu fungsi dimasukkan, penunjuk tumpukan dikurangi untuk mengalokasikan lebih banyak ruang pada tumpukan untuk variabel lokal (otomatis). Jika fungsi memiliki satu variabel 32 bit lokal, empat byte dikesampingkan pada stack. Ketika fungsi kembali, penunjuk tumpukan dipindahkan kembali untuk membebaskan area yang dialokasikan.
  • Jika suatu fungsi memiliki parameter, ini didorong ke tumpukan sebelum panggilan ke fungsi. Kode dalam fungsi ini kemudian dapat menavigasi tumpukan dari penunjuk tumpukan saat ini untuk menemukan nilai-nilai ini.
  • Panggilan fungsi Nesting bekerja seperti pesona. Setiap panggilan baru akan mengalokasikan parameter fungsi, alamat pengirim dan ruang untuk variabel lokal dan catatan aktivasi ini dapat ditumpuk untuk panggilan bersarang dan akan bersantai dengan cara yang benar ketika fungsi kembali.
  • Karena stack adalah blok memori terbatas, Anda dapat menyebabkan stack overflow dengan memanggil terlalu banyak fungsi yang bersarang dan/atau mengalokasikan terlalu banyak ruang untuk variabel lokal. Seringkali area memori yang digunakan untuk stack diatur sedemikian rupa sehingga penulisan di bawah bagian bawah (alamat terendah) stack akan memicu jebakan atau pengecualian pada CPU. Kondisi luar biasa ini kemudian dapat ditangkap oleh runtime dan dikonversi menjadi semacam pengecualian stack overflow.

The stack

Bisakah fungsi dialokasikan pada heap daripada stack?

Tidak, catatan aktivasi untuk fungsi (mis. Variabel lokal atau otomatis) dialokasikan pada stack yang digunakan tidak hanya untuk menyimpan variabel-variabel ini, tetapi juga untuk melacak panggilan fungsi yang disarangkan.

Bagaimana tumpukan dikelola benar-benar hingga lingkungan runtime. C menggunakan malloc dan C++ menggunakan new, tetapi banyak bahasa lain memiliki pengumpulan sampah.Namun, tumpukan adalah fitur tingkat rendah yang terkait erat dengan arsitektur prosesor. Menumbuhkan tumpukan ketika tidak ada cukup ruang tidak terlalu sulit karena dapat diimplementasikan dalam panggilan perpustakaan yang menangani tumpukan. Namun, menumbuhkan tumpukan seringkali tidak mungkin karena stack overflow hanya ditemukan ketika sudah terlambat; dan mematikan utas eksekusi adalah satu-satunya pilihan.

However, the stack is a more low-level feature closely tied to the processor architecture. Growing the heap when there is not enough space isn't too hard since it can be implemented in the library call that handles the heap. However, growing the stack is often impossible as the stack overflow only is discovered when it is too late; and shutting down the thread of execution is the only viable option.

685
Martin Liversage

Dalam kode C # berikut

public void Method1()
{
    int i = 4;
    int y = 2;
    class1 cls1 = new class1();
}

Begini cara memori dikelola

Picture of variables on the stack

Local Variables yang hanya perlu bertahan selama pemanggilan fungsi masuk ke stack. Heap digunakan untuk variabel yang seumur hidupnya kita tidak benar-benar tahu di muka tetapi kita berharap mereka bertahan beberapa saat. Dalam kebanyakan bahasa, penting bagi kita untuk mengetahui pada waktu kompilasi seberapa besar variabel jika kita ingin menyimpannya di stack. 

Objek (yang bervariasi dalam ukuran saat kita memperbaruinya) terus bertambah karena kita tidak tahu pada waktu pembuatan berapa lama mereka akan bertahan. Dalam banyak bahasa heap adalah sampah yang dikumpulkan untuk menemukan objek (seperti objek cls1) yang tidak lagi memiliki referensi. 

Di Jawa, sebagian besar objek masuk langsung ke tumpukan. Dalam bahasa seperti C/C++, struct dan kelas sering dapat tetap di stack ketika Anda tidak berurusan dengan pointer.

Informasi lebih lanjut dapat ditemukan di sini:

Perbedaan antara alokasi memori tumpukan dan tumpukan «timmurphy.org

dan di sini: 

Membuat Objek di Stack and Heap

Artikel ini adalah sumber gambar di atas: Enam konsep .NET penting: Stack, heap, tipe nilai, tipe referensi, tinju, dan unboxing - CodeProject

tapi ketahuilah itu mungkin mengandung beberapa ketidakakuratan. 

379
Snowcrash

Stack Ketika Anda memanggil suatu fungsi argumen ke fungsi itu ditambah beberapa overhead lainnya diletakkan di tumpukan. Beberapa info (seperti kemana harus kembali) juga disimpan di sana . Ketika Anda mendeklarasikan variabel di dalam fungsi Anda, variabel itu juga dialokasikan pada stack. 

Deallocating stack cukup sederhana karena Anda selalu melakukan deallocate dalam urutan terbalik di mana Anda mengalokasikan. Stack stuff ditambahkan saat Anda memasukkan fungsi, data yang sesuai dihapus saat Anda keluar dari mereka. Ini berarti Anda cenderung tetap berada dalam wilayah kecil tumpukan kecuali Anda memanggil banyak fungsi yang memanggil banyak fungsi lainnya (atau membuat solusi rekursif).

Heap Heap adalah nama generik untuk tempat Anda meletakkan data yang Anda buat dengan cepat. Jika Anda tidak tahu berapa banyak pesawat ruang angkasa yang akan dibuat oleh program Anda, Anda kemungkinan akan menggunakan operator baru (atau malloc atau yang setara) untuk membuat setiap pesawat ruang angkasa. Alokasi ini akan bertahan untuk sementara waktu, jadi kemungkinan kami akan membebaskan barang dalam urutan yang berbeda dari yang kami buat. 

Dengan demikian, tumpukan jauh lebih kompleks, karena akhirnya ada wilayah memori yang tidak terpakai disisipkan dengan potongan yang - memori menjadi terfragmentasi. Menemukan memori bebas dari ukuran yang Anda butuhkan adalah masalah yang sulit. Inilah sebabnya tumpukan harus dihindari (meskipun masih sering digunakan).

Implementasi Implementasi stack dan heap biasanya turun ke runtime/OS. Seringkali gim dan aplikasi lain yang kinerjanya kritis membuat solusi memori mereka sendiri yang mengambil banyak memori dari tumpukan dan kemudian menyajikannya secara internal untuk menghindari mengandalkan OS untuk memori. 

Ini hanya praktis jika penggunaan memori Anda sangat berbeda dari norma - yaitu untuk game di mana Anda memuat level dalam satu operasi besar dan dapat membuang semuanya jauh dalam operasi besar lainnya.

Lokasi fisik dalam memori Ini kurang relevan daripada yang Anda pikirkan karena teknologi yang disebut Memori Virtual yang membuat program Anda berpikir bahwa Anda memiliki akses ke alamat tertentu di mana data fisik berada di tempat lain ( bahkan pada hard disk!). Alamat yang Anda dapatkan untuk tumpukan semakin meningkat saat pohon panggilan Anda semakin dalam. Alamat untuk heap tidak dapat diprediksi (yaitu khusus untuk implimentasi) dan terus terang tidak penting.

194
Tom Leys

Untuk memperjelas, jawaban ini memiliki informasi yang salah ( thomas memperbaiki jawabannya setelah komentar, keren :)). Jawaban lain hanya menghindari menjelaskan apa artinya alokasi statis. Jadi saya akan menjelaskan tiga bentuk alokasi utama dan bagaimana mereka biasanya berhubungan dengan heap, stack, dan segmen data di bawah ini. Saya juga akan menunjukkan beberapa contoh dalam C/C++ dan Python untuk membantu orang mengerti.

Variabel "Statis" (AKA dialokasikan secara statis) tidak dialokasikan pada stack. Jangan berasumsi begitu - banyak orang melakukannya hanya karena "statis" terdengar sangat mirip "tumpukan". Mereka benar-benar ada di tumpukan atau tumpukan. Merupakan bagian dari apa yang disebut segmen data .

Namun, umumnya lebih baik mempertimbangkan "scope" dan "lifetime" daripada "stack" dan "heap".

Lingkup mengacu pada bagian kode mana yang dapat mengakses variabel. Secara umum kita berpikir tentang cakupan lokal (hanya dapat diakses oleh fungsi saat ini) versus cakupan global (dapat diakses di mana saja) meskipun ruang lingkup bisa menjadi jauh lebih kompleks.

Seumur hidup mengacu pada ketika variabel dialokasikan dan dialokasikan selama pelaksanaan program. Biasanya kita memikirkan alokasi statis (variabel akan bertahan selama seluruh durasi program, menjadikannya berguna untuk menyimpan informasi yang sama di beberapa panggilan fungsi) versus alokasi otomatis (variabel hanya akan tetap ada selama satu panggilan ke suatu fungsi, membuatnya berguna untuk menyimpan informasi yang hanya digunakan selama fungsi Anda dan dapat dibuang setelah Anda selesai) versus alokasi dinamis (variabel yang durasinya ditentukan saat runtime, alih-alih waktu kompilasi seperti statis atau otomatis ).

Meskipun sebagian besar kompiler dan interpreter mengimplementasikan perilaku ini dengan cara yang sama dalam hal menggunakan tumpukan, tumpukan, dll, kompiler kadang-kadang dapat melanggar konvensi ini jika ingin selama perilaku itu benar. Misalnya, karena pengoptimalan, variabel lokal mungkin hanya ada dalam register atau dihapus seluruhnya, meskipun sebagian besar variabel lokal ada di tumpukan. Seperti yang telah ditunjukkan dalam beberapa komentar, Anda bebas menerapkan kompiler yang bahkan tidak menggunakan stack atau heap, tetapi sebaliknya beberapa mekanisme penyimpanan lainnya (jarang dilakukan, karena tumpukan dan tumpukan sangat bagus untuk ini).

Saya akan memberikan beberapa kode C beranotasi sederhana untuk menggambarkan semua ini. Cara terbaik untuk belajar adalah menjalankan program di bawah debugger dan melihat perilaku tersebut. Jika Anda lebih suka membaca python, lompat ke akhir jawaban :)

// Statically allocated in the data segment when the program/DLL is first loaded
// Deallocated when the program/DLL exits
// scope - can be accessed from anywhere in the code
int someGlobalVariable;

// Statically allocated in the data segment when the program is first loaded
// Deallocated when the program/DLL exits
// scope - can be accessed from anywhere in this particular code file
static int someStaticVariable;

// "someArgument" is allocated on the stack each time MyFunction is called
// "someArgument" is deallocated when MyFunction returns
// scope - can be accessed only within MyFunction()
void MyFunction(int someArgument) {

    // Statically allocated in the data segment when the program is first loaded
    // Deallocated when the program/DLL exits
    // scope - can be accessed only within MyFunction()
    static int someLocalStaticVariable;

    // Allocated on the stack each time MyFunction is called
    // Deallocated when MyFunction returns
    // scope - can be accessed only within MyFunction()
    int someLocalVariable;

    // A *pointer* is allocated on the stack each time MyFunction is called
    // This pointer is deallocated when MyFunction returns
    // scope - the pointer can be accessed only within MyFunction()
    int* someDynamicVariable;

    // This line causes space for an integer to be allocated in the heap
    // when this line is executed. Note this is not at the beginning of
    // the call to MyFunction(), like the automatic variables
    // scope - only code within MyFunction() can access this space
    // *through this particular variable*.
    // However, if you pass the address somewhere else, that code
    // can access it too
    someDynamicVariable = new int;


    // This line deallocates the space for the integer in the heap.
    // If we did not write it, the memory would be "leaked".
    // Note a fundamental difference between the stack and heap
    // the heap must be managed. The stack is managed for us.
    delete someDynamicVariable;

    // In other cases, instead of deallocating this heap space you
    // might store the address somewhere more permanent to use later.
    // Some languages even take care of deallocation for you... but
    // always it needs to be taken care of at runtime by some mechanism.

    // When the function returns, someArgument, someLocalVariable
    // and the pointer someDynamicVariable are deallocated.
    // The space pointed to by someDynamicVariable was already
    // deallocated prior to returning.
    return;
}

// Note that someGlobalVariable, someStaticVariable and
// someLocalStaticVariable continue to exist, and are not
// deallocated until the program exits.

Contoh yang sangat pedih tentang mengapa penting untuk membedakan antara masa hidup dan ruang lingkup adalah bahwa variabel dapat memiliki ruang lingkup lokal tetapi seumur hidup statis - misalnya, "someLocalStaticVariable" dalam contoh kode di atas. Variabel-variabel seperti itu dapat membuat kebiasaan penamaan kita yang umum tetapi tidak resmi sangat membingungkan. Misalnya ketika kita mengatakan "lokal" kita biasanya berarti "variabel yang dialokasikan secara lokal secara otomatis" dan ketika kita mengatakan global kita biasanya berarti "variabel yang dialokasikan secara global yang dialokasikan secara global ". Sayangnya ketika datang ke hal-hal seperti "file scoped variabel yang dialokasikan secara statis" banyak orang hanya mengatakan ... "huh ???".

Beberapa pilihan sintaks dalam C/C++ memperburuk masalah ini - misalnya banyak orang berpikir variabel global tidak "statis" karena sintaks yang ditunjukkan di bawah ini.

int var1; // Has global scope and static allocation
static int var2; // Has file scope and static allocation

int main() {return 0;}

Perhatikan bahwa menempatkan kata kunci "statis" dalam deklarasi di atas mencegah var2 memiliki lingkup global. Namun demikian, global var1 memiliki alokasi statis. Ini tidak intuitif! Untuk alasan ini, saya mencoba untuk tidak pernah menggunakan kata "statis" ketika menggambarkan ruang lingkup, dan sebaliknya mengatakan sesuatu seperti "file" atau "file terbatas" ruang lingkup. Namun banyak orang menggunakan frasa "statis" atau "ruang lingkup statis" untuk menggambarkan variabel yang hanya dapat diakses dari satu file kode. Dalam konteks seumur hidup, "statis" selalu berarti variabel dialokasikan pada awal program dan dideallocated ketika program keluar.

Beberapa orang menganggap konsep ini spesifik C/C++. Mereka tidak. Sebagai contoh, sampel Python di bawah ini menggambarkan ketiga jenis alokasi (ada beberapa perbedaan halus dalam bahasa yang ditafsirkan yang tidak akan saya bahas di sini).

from datetime import datetime

class Animal:
    _FavoriteFood = 'Undefined' # _FavoriteFood is statically allocated

    def PetAnimal(self):
        curTime = datetime.time(datetime.now()) # curTime is automatically allocatedion
        print("Thank you for petting me. But it's " + str(curTime) + ", you should feed me. My favorite food is " + self._FavoriteFood)

class Cat(Animal):
    _FavoriteFood = 'tuna' # Note since we override, Cat class has its own statically allocated _FavoriteFood variable, different from Animal's

class Dog(Animal):
    _FavoriteFood = 'steak' # Likewise, the Dog class gets its own static variable. Important to note - this one static variable is shared among all instances of Dog, hence it is not dynamic!


if __== "__main__":
    whiskers = Cat() # Dynamically allocated
    fido = Dog() # Dynamically allocated
    rinTinTin = Dog() # Dynamically allocated

    whiskers.PetAnimal()
    fido.PetAnimal()
    rinTinTin.PetAnimal()

    Dog._FavoriteFood = 'milkbones'
    whiskers.PetAnimal()
    fido.PetAnimal()
    rinTinTin.PetAnimal()

# Output is:
# Thank you for petting me. But it's 13:05:02.255000, you should feed me. My favorite food is tuna
# Thank you for petting me. But it's 13:05:02.255000, you should feed me. My favorite food is steak
# Thank you for petting me. But it's 13:05:02.255000, you should feed me. My favorite food is steak
# Thank you for petting me. But it's 13:05:02.255000, you should feed me. My favorite food is tuna
# Thank you for petting me. But it's 13:05:02.255000, you should feed me. My favorite food is milkbones
# Thank you for petting me. But it's 13:05:02.256000, you should feed me. My favorite food is milkbones
174
davec

Yang lain telah menjawab sapuan luas dengan cukup baik, jadi saya akan memberikan beberapa detail.

  1. Stack dan heap tidak harus tunggal. Situasi umum di mana Anda memiliki lebih dari satu tumpukan adalah jika Anda memiliki lebih dari satu utas dalam suatu proses. Dalam hal ini setiap utas memiliki tumpukan sendiri. Anda juga dapat memiliki lebih dari satu tumpukan, misalnya beberapa konfigurasi DLL dapat mengakibatkan DLL yang berbeda mengalokasikan dari tumpukan yang berbeda, itulah sebabnya mengapa itu umumnya ide buruk untuk melepaskan memori yang dialokasikan oleh perpustakaan yang berbeda.

  2. Dalam C Anda bisa mendapatkan manfaat dari alokasi panjang variabel melalui penggunaan -okasikana , yang mengalokasikan pada stack, sebagai lawan dari alokasi, yang mengalokasikan pada heap. Memori ini tidak akan bertahan dari pernyataan pengembalian Anda, tetapi ini berguna untuk buffer awal.

  3. Membuat buffer sementara yang besar di Windows yang tidak Anda gunakan banyak tidak gratis. Ini karena kompiler akan menghasilkan loop probe stack yang dipanggil setiap kali fungsi Anda dimasukkan untuk memastikan stack ada (karena Windows menggunakan halaman penjaga tunggal di akhir tumpukan Anda untuk mendeteksi kapan perlu menumbuhkan tumpukan. Jika Anda mengakses memori lebih dari satu halaman dari ujung tumpukan Anda akan crash). Contoh:

void myfunction()
{
   char big[10000000];
   // Do something that only uses for first 1K of big 99% of the time.
}
158
Don Neufeld

Orang lain secara langsung menjawab pertanyaan Anda, tetapi ketika mencoba memahami tumpukan dan tumpukan, saya pikir akan sangat membantu untuk mempertimbangkan tata letak memori dari proses UNIX tradisional (tanpa utas dan mmap()- pengalokasi berbasis __). Halaman Memory Management Glosarium web memiliki diagram tata letak memori ini.

Tumpukan dan tumpukan secara tradisional terletak di ujung yang berlawanan dari ruang alamat virtual proses. Tumpukan tumbuh secara otomatis ketika diakses, hingga ukuran yang ditentukan oleh kernel (yang dapat disesuaikan dengan setrlimit(RLIMIT_STACK, ...)). Tumpukan tumbuh ketika pengalokasi memori memanggil brk() atau sbrk() sistem panggilan, memetakan lebih banyak halaman memori fisik ke dalam ruang alamat virtual proses. 

Dalam sistem tanpa memori virtual, seperti beberapa sistem tertanam, tata letak dasar yang sama sering berlaku, kecuali tumpukan dan tumpukan diperbaiki dalam ukuran. Namun, dalam sistem tertanam lainnya (seperti yang berbasis pada mikrokontroler PIC Microchip), tumpukan program adalah blok memori terpisah yang tidak dapat dialamatkan oleh instruksi perpindahan data, dan hanya dapat dimodifikasi atau dibaca secara tidak langsung melalui instruksi aliran program (panggilan kembali, dll.). Arsitektur lain, seperti prosesor Intel Itanium, memiliki banyak tumpukan . Dalam pengertian ini, tumpukan adalah elemen arsitektur CPU.

127
bk1e

Tumpukan adalah bagian dari memori yang dapat dimanipulasi melalui beberapa instruksi bahasa kunci Majelis, seperti 'pop' (menghapus dan mengembalikan nilai dari tumpukan) dan 'Push' (Mendorong nilai ke tumpukan), tetapi juga memanggil ( panggil subrutin - ini mendorong alamat untuk kembali ke tumpukan) dan kembali (kembali dari subrutin - ini memunculkan alamat dari tumpukan dan melompat ke sana). Ini adalah wilayah memori di bawah register penunjuk tumpukan, yang dapat diatur sesuai kebutuhan. Tumpukan juga digunakan untuk meneruskan argumen ke subrutin, dan juga untuk menjaga nilai dalam register sebelum memanggil subrutin.

Tumpukan adalah sebagian dari memori yang diberikan kepada aplikasi oleh sistem operasi, biasanya melalui syscall seperti malloc. Pada OS modern, memori ini adalah sekumpulan halaman yang hanya dapat diakses oleh proses panggilan.

Ukuran tumpukan ditentukan saat runtime, dan umumnya tidak bertambah setelah program diluncurkan. Dalam program C, tumpukan harus cukup besar untuk menampung setiap variabel yang dideklarasikan dalam setiap fungsi. Tumpukan akan tumbuh secara dinamis sesuai kebutuhan, tetapi OS pada akhirnya membuat panggilan (sering akan menumpuk lebih dari nilai yang diminta oleh malloc, sehingga setidaknya beberapa mallocs di masa depan tidak perlu kembali ke kernel untuk dapatkan lebih banyak memori. Perilaku ini sering kali dapat disesuaikan)

Karena Anda telah mengalokasikan stack sebelum meluncurkan program, Anda tidak perlu melakukan malloc sebelum Anda dapat menggunakan stack, jadi itu sedikit keuntungan di sana. Dalam praktiknya, sangat sulit untuk memprediksi apa yang akan cepat dan apa yang akan lambat dalam sistem operasi modern yang memiliki subsistem memori virtual, karena bagaimana halaman diimplementasikan dan di mana mereka disimpan adalah detail implementasi. 

108
Daniel Papasian

Saya pikir banyak orang telah memberi Anda jawaban yang benar tentang masalah ini.

Namun, satu detail yang terlewatkan adalah "tumpukan" itu sebenarnya mungkin disebut "toko gratis". Alasan untuk perbedaan ini adalah bahwa toko bebas asli diimplementasikan dengan struktur data yang dikenal sebagai "tumpukan binomial." Karena alasan itu, pengalokasian dari implementasi awal malloc ()/free () adalah alokasi dari heap. Namun, di zaman modern ini, sebagian besar toko gratis diimplementasikan dengan struktur data yang sangat rumit yang bukan tumpukan binomial.

107
Heath

Apa itu tumpukan?

Tumpukan adalah tumpukan benda, biasanya yang tertata rapi.

 Enter image description here

Tumpukan dalam arsitektur komputasi adalah wilayah memori tempat data ditambahkan atau dihapus dengan cara masuk terakhir keluar pertama. 
Dalam aplikasi multi-utas, setiap utas akan memiliki tumpukan sendiri.

Apa itu heap?

Tumpukan adalah kumpulan benda-benda yang tertumpuk secara acak.

 Enter image description here

Dalam arsitektur komputasi heap adalah area memori yang dialokasikan secara dinamis yang dikelola secara otomatis oleh sistem operasi atau perpustakaan manajer memori. 
Memori pada heap dialokasikan, deallocated, dan diubah ukurannya secara teratur selama eksekusi program, dan ini dapat menyebabkan masalah yang disebut fragmentasi. 
Fragmentasi terjadi ketika objek memori dialokasikan dengan ruang kecil di antaranya yang terlalu kecil untuk menampung objek memori tambahan. 
Hasil bersih adalah persentase ruang tumpukan yang tidak dapat digunakan untuk alokasi memori lebih lanjut.

Berdua bersama

Dalam aplikasi multi-utas, setiap utas akan memiliki tumpukan sendiri. Tapi, semua utas yang berbeda akan berbagi tumpukan. 
Karena utas yang berbeda berbagi tumpukan dalam aplikasi multi-utas, ini juga berarti bahwa harus ada koordinasi antara utas sehingga mereka tidak mencoba mengakses dan memanipulasi bagian memori yang sama di tumpukan di waktu yang sama.

Manakah yang lebih cepat - tumpukan atau tumpukan? Dan mengapa?

Tumpukan jauh lebih cepat daripada tumpukan. 
Ini karena cara memori dialokasikan pada stack. 
Mengalokasikan memori pada stack adalah sesederhana memindahkan pointer stack ke atas.

Bagi orang-orang yang baru dalam pemrograman, mungkin ide yang baik untuk menggunakan stack karena lebih mudah. 
Karena tumpukannya kecil, Anda ingin menggunakannya ketika Anda tahu persis berapa banyak memori yang Anda perlukan untuk data Anda, atau jika Anda tahu ukuran data Anda sangat kecil. 
Lebih baik menggunakan heap ketika Anda tahu bahwa Anda akan membutuhkan banyak memori untuk data Anda, atau Anda hanya tidak yakin berapa banyak memori yang akan Anda butuhkan (seperti dengan array dinamis).

Model Memori Java

 Enter image description here

Tumpukan adalah area memori tempat variabel lokal (termasuk parameter metode) disimpan. Ketika datang ke variabel objek, ini hanyalah referensi (pointer) ke objek aktual di heap.
Setiap kali suatu objek dibuat, sepotong memori tumpukan disisihkan untuk menyimpan data (keadaan) dari objek itu. Karena objek dapat berisi objek lain, beberapa data ini sebenarnya bisa menyimpan referensi ke objek bersarang.

101
Shreyos Adikari

Anda dapat melakukan beberapa hal menarik dengan tumpukan. Misalnya, Anda memiliki fungsi seperti -okasikana (dengan asumsi Anda bisa melewati peringatan berlebihan tentang penggunaannya), yang merupakan bentuk malloc yang secara khusus menggunakan stack, bukan heap, untuk memori.

Yang mengatakan, kesalahan memori berbasis stack adalah beberapa yang terburuk yang pernah saya alami. Jika Anda menggunakan memori tumpukan, dan Anda melampaui batas-batas blok yang dialokasikan, Anda memiliki peluang yang layak untuk memicu kesalahan segmen. (Tidak 100%: blok Anda mungkin berdekatan dengan yang lain yang sebelumnya Anda alokasikan). Tetapi karena variabel yang dibuat pada tumpukan selalu berdekatan satu sama lain, penulisan di luar batas dapat mengubah nilai variabel lain. Saya telah belajar bahwa setiap kali saya merasa bahwa program saya telah berhenti mematuhi hukum logika, itu mungkin buffer overflow.

87
Peter

Secara sederhana, stack adalah tempat variabel lokal dibuat. Juga, setiap kali Anda memanggil subrutin penghitung program (penunjuk ke instruksi mesin berikutnya) dan register penting apa pun, dan terkadang parameter didorong pada tumpukan. Kemudian variabel lokal apa pun di dalam subrutin didorong ke tumpukan (dan digunakan dari sana). Ketika subrutin selesai, semua itu akan muncul kembali dari tumpukan. PC dan mendaftar data didapat dan dimasukkan kembali ke tempatnya semula, sehingga program Anda dapat berjalan dengan cara yang menyenangkan.

Heap adalah area alokasi memori dinamis yang terbuat dari memori (panggilan "baru" atau "alokasikan" eksplisit). Ini adalah struktur data khusus yang dapat melacak blok memori dengan berbagai ukuran dan status alokasi mereka.

Dalam sistem "klasik" RAM diletakkan sedemikian rupa sehingga penumpukan tumpukan dimulai di bagian bawah memori, penumpukan tumpukan dimulai di bagian atas, dan mereka tumbuh saling berhadapan. Jika mereka tumpang tindih, Anda kehabisan RAM. Itu tidak bekerja dengan OS multi-threaded modern sekalipun. Setiap utas harus memiliki tumpukan sendiri, dan itu dapat dibuat secara dinamis.

84
T.E.D.

Dari WikiAnwser.

Tumpukan

Ketika suatu fungsi atau metode memanggil fungsi lain yang pada gilirannya memanggil fungsi lain, dll., Eksekusi semua fungsi tersebut tetap ditunda hingga fungsi terakhir mengembalikan nilainya.

Rantai panggilan fungsi yang ditangguhkan ini adalah tumpukan, karena elemen-elemen dalam tumpukan (panggilan fungsi) saling bergantung.

Tumpukan penting untuk dipertimbangkan dalam penanganan pengecualian dan eksekusi ulir.

Tumpukan

Heap hanyalah memori yang digunakan oleh program untuk menyimpan variabel . Elemen heap (variabel) tidak memiliki ketergantungan satu sama lain dan selalu dapat diakses secara acak kapan saja.

78
devXen

Stack

  • Akses sangat cepat
  • Tidak harus secara eksplisit mendelegasikan variabel
  • Ruang dikelola secara efisien oleh CPU, memori tidak akan menjadi terfragmentasi
  • Hanya variabel lokal
  • Batas ukuran tumpukan (bergantung pada OS)
  • Variabel tidak dapat diubah ukurannya

Tumpukan

  • Variabel dapat diakses secara global
  • Tidak ada batasan ukuran memori
  • (Relatif) akses lebih lambat
  • Tidak ada jaminan penggunaan ruang yang efisien, memori dapat menjadi terfragmentasi seiring waktu ketika blok memori dialokasikan, lalu dibebaskan
  • Anda harus mengelola memori (Anda bertanggung jawab untuk mengalokasikan dan membebaskan variabel)
  • Variabel dapat diubah ukurannya menggunakan realloc ()
50
unknown

OK, sederhananya dan dengan kata singkat, artinya dipesan dan tidak dipesan ...!

Stack: Dalam tumpukan item, segalanya saling terkait, artinya akan lebih cepat dan lebih efisien untuk diproses! ... 

Jadi selalu ada indeks untuk menunjuk item tertentu, juga pemrosesan akan lebih cepat, ada hubungan antara item juga! ...

Heap: Tanpa pesanan, pemrosesan akan lebih lambat dan nilai-nilai kacau bersama tanpa urutan atau indeks tertentu ... ada acak dan tidak ada hubungan di antara mereka ... sehingga waktu eksekusi dan penggunaan dapat bervariasi. ..

Saya juga membuat gambar di bawah ini untuk menunjukkan bagaimana tampilannya:

 enter image description here

38
Alireza

Pada 1980-an, UNIX berkembang biak seperti kelinci dengan perusahaan-perusahaan besar menggulirkannya sendiri. Exxon memiliki satu seperti lusinan nama merek yang hilang karena sejarah . Bagaimana memori diletakkan adalah pada kebijaksanaan banyak pelaksana.

Sebuah program C yang khas diletakkan datar dalam memori dengansebuah peluang untuk meningkat dengan mengubah nilai brk () . Biasanya, HEAP tepat di bawah nilai brk ini .__ dan meningkatkan brk meningkatkan jumlah yang tersedia tumpukan.

STACK tunggal biasanya merupakan area di bawah HEAP yang merupakan saluran memori Tidak mengandung nilai sampai bagian atas blok memori tetap berikutnya . Blok berikutnya ini sering KODE yang dapat ditimpa oleh data tumpukanin salah satu peretasan terkenal di masanya.

Satu blok memori yang khas adalah BSS (blok bernilai nol) Yang secara tidak sengaja tidak diunggulkan dalam satu penawaran pabrikan . Lainnya adalah DATA yang berisi nilai yang diinisialisasi, termasuk string dan angka . (Runtime C), utama, fungsi, dan perpustakaan.

Munculnya memori virtual dalam UNIX mengubah banyak kendala . Tidak ada alasan obyektif mengapa blok-blok ini harus bersebelahan, Atau ukurannya tetap, atau dipesan dengan cara tertentu sekarang . Tentu saja, sebelum UNIX adalah Multics yang tidak mengalami kendala ini . Berikut ini adalah skema yang menunjukkan salah satu tata letak memori pada masa itu.

A typical 1980s style UNIX C program memory layout

35
jlettvin

stack, heap dan data setiap proses dalam memori virtual:

 stack, heap and static data

29
Yousha Aleayoub

Beberapa sen: Saya pikir, akan baik untuk menggambar memori grafis dan lebih sederhana:

 This is my vision of process memory construction with simplification for more easy understanding wht happening


Tanda panah - menunjukkan tempat menumpuk dan menumpuk, memproses ukuran tumpukan memiliki batas, ditentukan dalam OS, batas ukuran tumpukan benang dengan parameter di utas membuat API biasanya. Heap biasanya dibatasi oleh proses ukuran memori virtual maksimum, misalnya 32 bit 2-4 GB.

Jadi cara sederhana: tumpukan proses adalah umum untuk proses dan semua utas di dalamnya, gunakan untuk alokasi memori dalam kasus umum dengan sesuatu seperti malloc ().

Stack adalah memori cepat untuk menyimpan dalam fungsi umum, pointer dan variabel pengembalian fungsi, diproses sebagai parameter dalam panggilan fungsi, variabel fungsi lokal.

24
Maxim Akristiniy

Saya memiliki sesuatu untuk dibagikan, meskipun poin utama sudah dibahas.

Stack  

  • Akses sangat cepat.
  • Disimpan dalam RAM.
  • Panggilan fungsi dimuat di sini bersama dengan variabel lokal dan parameter fungsi yang diteruskan.
  • Ruang dibebaskan secara otomatis ketika program keluar dari cakupan.
  • Disimpan dalam memori sekuensial.

Tumpukan

  • Akses lambat dibandingkan dengan Stack.
  • Disimpan dalam RAM.
  • Variabel yang dibuat secara dinamis disimpan di sini, yang nantinya membutuhkan pembebasan memori yang dialokasikan setelah digunakan.
  • Disimpan di mana pun alokasi memori dilakukan, selalu diakses oleh pointer.

Catatan menarik:

  • Jika pemanggilan fungsi telah disimpan di heap, itu akan menghasilkan 2 poin berantakan:
    1. Karena penyimpanan berurutan dalam tumpukan, eksekusi lebih cepat. Penyimpanan dalam tumpukan akan menghasilkan konsumsi waktu yang sangat besar sehingga membuat seluruh program berjalan lebih lambat.
    2. Jika fungsi disimpan di heap (penyimpanan berantakan menunjuk oleh pointer), tidak akan ada cara untuk kembali ke alamat pemanggil kembali (yang tumpukan memberikan karena penyimpanan berurutan dalam memori).
12

Banyak jawaban yang benar sebagai konsep, tetapi kita harus mencatat bahwa setumpuk diperlukan oleh perangkat keras (mis. Mikroprosesor) untuk memungkinkan pemanggilan subrutin (PANGGILAN dalam bahasa Assembly ..). (OOP guys akan menyebutnya metode)

Pada tumpukan Anda menyimpan alamat kembali dan panggilan → Push/ret → pop dikelola langsung di perangkat keras.

Anda dapat menggunakan tumpukan untuk melewatkan parameter .. bahkan jika itu lebih lambat daripada menggunakan register (akankah seorang guru mikroprosesor mengatakan atau buku BIOS 1980-an yang bagus ...)

  • Tanpa stack no mikroprosesor dapat bekerja. (kami tidak dapat membayangkan program, bahkan dalam bahasa Assembly, tanpa subrutin/fungsi)
  • Tanpa tumpukan itu bisa. (Suatu program bahasa Assembly dapat bekerja tanpa, karena heap adalah konsep OS, sebagai malloc, itu adalah panggilan OS/Lib.

Penggunaan tumpukan lebih cepat karena:

  • Apakah perangkat keras, dan bahkan Push/pop sangat efisien.
  • malloc mengharuskan memasuki mode kernel, menggunakan kunci/semaphore (atau primitif sinkronisasi lainnya) mengeksekusi beberapa kode dan mengelola beberapa struktur yang diperlukan untuk melacak alokasi.
8
ingconti

Wow! Begitu banyak jawaban dan saya rasa salah satu dari mereka tidak benar ...

1) Di mana dan apa mereka (secara fisik dalam memori komputer nyata)?

Tumpukan adalah memori yang dimulai sebagai alamat memori tertinggi yang dialokasikan untuk gambar program Anda, dan kemudian berkurang nilainya dari sana. Ini dicadangkan untuk parameter fungsi yang disebut dan untuk semua variabel sementara yang digunakan dalam fungsi.

Ada dua tumpukan: publik dan pribadi.

Tumpukan pribadi dimulai pada batas 16-byte (untuk program 64-bit) atau batas 8-byte (untuk program 32-bit) setelah kode byte terakhir dalam program Anda, dan kemudian meningkat nilainya dari sana. Ini juga disebut heap default.

Jika tumpukan pribadi menjadi terlalu besar itu akan tumpang tindih area tumpukan, seperti tumpukan akan tumpang tindih tumpukan jika terlalu besar. Karena tumpukan dimulai pada alamat yang lebih tinggi dan bekerja turun ke alamat yang lebih rendah, dengan peretasan yang tepat Anda bisa membuat tumpukan itu begitu besar sehingga akan menyerbu area tumpukan pribadi dan tumpang tindih area kode. Triknya adalah tumpang tindih dengan area kode yang bisa Anda kaitkan ke dalam kode. Agak sulit untuk dilakukan dan Anda berisiko crash program, tetapi mudah dan sangat efektif.

Tumpukan publik berada di ruang memori itu sendiri di luar ruang gambar program Anda. Memori inilah yang akan disedot ke hard disk jika sumber daya memori menjadi langka.

2) Sejauh mana mereka dikendalikan oleh runtime OS atau bahasa?

Tumpukan dikendalikan oleh programmer, tumpukan pribadi dikelola oleh OS, dan tumpukan publik tidak dikendalikan oleh siapa pun karena ini adalah layanan OS - Anda membuat permintaan dan apakah itu diberikan atau ditolak.

2b) Apa cakupannya?

Semuanya bersifat global untuk program ini, tetapi isinya dapat bersifat pribadi, publik, atau global.

2c) Apa yang menentukan ukuran masing-masing?

Ukuran tumpukan dan tumpukan pribadi ditentukan oleh opsi runtime kompiler Anda. Tumpukan publik diinisialisasi pada saat runtime menggunakan parameter ukuran.

2d) Apa yang membuatnya lebih cepat?

Mereka tidak dirancang untuk menjadi cepat, mereka dirancang untuk berguna. Bagaimana programmer menggunakannya menentukan apakah mereka "cepat" atau "lambat"

REF:

https://norasandler.com/2019/02/18/Write-a-Compiler-10.html

https://docs.Microsoft.com/en-us/windows/desktop/api/heapapi/nf-heapapi-getprocessheap

https://docs.Microsoft.com/en-us/windows/desktop/api/heapapi/nf-heapapi-heapcreate

3
ar18

strategi alokasi penyimpanan dengan bahasa pemrograman 

MEMORY IN C - STACK, THE HEAP, DAN STATIC

 enter image description here  MEMORY IN C – THE STACK, THE HEAP, AND STATIC

  1. OP: Sejauh mana mereka dikendalikan oleh runtime OS atau bahasa?

Saya ingin menambahkan beberapa hal tentang pertanyaan penting ini: 

OS dan Runtime Bahasa Umum 

Komponen Utama dari.NET Framework  enter image description here Net Framework 4.5 Arsitektur  enter image description here

Komponen CLR  Components of CLR  enter image description here  enter image description here  enter image description here

0
leonidaa