Panggil fungsi "DoStackOverflow" sekali dari kode Anda dan Anda akan mendapatkan EStackOverflow kesalahan yang diajukan oleh Delphi dengan pesan "stack overflow".
fungsi DoStackOverflow: integer;
mulai
hasil: = 1 + DoStackOverflow;
akhir;
Apa ini "tumpukan" dan mengapa ada limpahan di sana menggunakan kode di atas?
Jadi, fungsi DoStackOverflow secara rekursif memanggil dirinya sendiri - tanpa "strategi keluar" - hanya terus berputar dan tidak pernah keluar.
Perbaikan cepat, Anda akan lakukan, adalah untuk menghapus bug jelas yang Anda miliki, dan memastikan fungsi ada di beberapa titik (sehingga kode Anda dapat terus mengeksekusi dari tempat Anda memanggil fungsi).
Anda pindah, dan Anda tidak pernah melihat ke belakang, tidak peduli tentang bug / pengecualian seperti yang sekarang dipecahkan.
Namun, pertanyaannya tetap: apa tumpukan ini dan mengapa ada limpahan?
Memori di Aplikasi Delphi Anda
Ketika Anda memulai pemrograman dalam Delphi, Anda mungkin mengalami bug seperti yang di atas, Anda akan menyelesaikannya dan melanjutkan. Yang ini terkait dengan alokasi memori. Sebagian besar waktu Anda tidak akan peduli tentang alokasi memori selama Anda
bebaskan apa yang Anda buat.Ketika Anda mendapatkan lebih banyak pengalaman di Delphi, Anda mulai membuat kelas Anda sendiri, instantiate mereka, peduli tentang manajemen memori dan sama.
Anda akan sampai pada titik di mana Anda akan membaca, di Bantuan, semacamnya "Variabel lokal (dideklarasikan dalam prosedur dan fungsi) berada di aplikasi tumpukan." dan juga Kelas adalah tipe referensi, sehingga tidak disalin pada tugas, mereka dilewatkan oleh referensi, dan mereka dialokasikan pada tumpukan.
Jadi, apa itu "tumpukan" dan apa yang "tumpukan"?
Tumpukan vs Tumpukan
Menjalankan aplikasi Anda di Windows, ada tiga area di memori tempat aplikasi Anda menyimpan data: memori global, heap, dan stack.
Variabel global (nilai / datanya) disimpan dalam memori global. Memori untuk variabel global dicadangkan oleh aplikasi Anda ketika program dimulai dan tetap dialokasikan sampai program Anda berakhir. Memori untuk variabel global disebut "segmen data".
Karena memori global hanya sekali dialokasikan dan dibebaskan pada penghentian program, kami tidak peduli tentang hal itu dalam artikel ini.
Stack dan heap adalah tempat alokasi memori dinamis terjadi: ketika Anda membuat variabel untuk suatu fungsi, ketika Anda membuat instance kelas ketika Anda mengirim parameter ke suatu fungsi dan menggunakan / meneruskan hasilnya nilai.
Apa itu Stack?
Ketika Anda mendeklarasikan variabel di dalam suatu fungsi, memori yang diperlukan untuk menyimpan variabel dialokasikan dari stack. Anda cukup menulis "var x: integer", gunakan "x" di fungsi Anda, dan ketika fungsi keluar, Anda tidak peduli tentang alokasi memori atau membebaskan. Ketika variabel keluar dari ruang lingkup (kode keluar dari fungsi), memori yang diambil pada stack dibebaskan.
Memori tumpukan dialokasikan secara dinamis menggunakan pendekatan LIFO ("last in first out").
Di Program Delphi, memori tumpukan digunakan oleh
- Variabel rutin lokal (metode, prosedur, fungsi).
- Parameter rutin dan tipe pengembalian.
- Fungsi Windows API panggilan.
- Rekaman (inilah sebabnya Anda tidak harus secara eksplisit membuat turunan jenis rekaman).
Anda tidak harus secara eksplisit membebaskan memori pada stack, karena memori secara otomatis dialokasikan untuk Anda ketika Anda, misalnya, mendeklarasikan variabel lokal ke suatu fungsi. Ketika fungsi keluar (kadang-kadang bahkan sebelum karena optimasi kompiler Delphi) memori untuk variabel akan secara otomatis dibebaskan secara ajaib.
Tumpuk ukuran memori secara default, cukup besar untuk program Delphi Anda (serumit). Nilai "Ukuran Tumpukan Maksimum" dan "Ukuran Tumpukan Minimum" pada opsi Linker untuk proyek Anda menentukan nilai default - dalam 99,99% Anda tidak perlu mengubah ini.
Pikirkan tumpukan sebagai tumpukan blok memori. Ketika Anda mendeklarasikan / menggunakan variabel lokal, manajer memori Delphi akan memilih blok dari atas, menggunakannya, dan ketika tidak diperlukan lagi akan dikembalikan ke stack.
Memiliki memori variabel lokal yang digunakan dari stack, variabel lokal tidak diinisialisasi ketika dideklarasikan. Deklarasikan variabel "var x: integer" di beberapa fungsi dan coba baca nilai ketika Anda memasukkan fungsi - x akan memiliki beberapa nilai "nol" yang aneh. Jadi, selalu inisialisasi (atau tetapkan nilai) ke variabel lokal Anda sebelum Anda membaca nilainya.
Karena LIFO, operasi stack (alokasi memori) berlangsung cepat karena hanya beberapa operasi (push, pop) yang diperlukan untuk mengelola stack.
Apa itu Heap?
Tumpukan adalah wilayah memori tempat memori yang dialokasikan secara dinamis disimpan. Saat Anda membuat instance kelas, memori dialokasikan dari heap.
Dalam program Delphi, heap memory digunakan oleh / kapan
- Membuat instance kelas.
- Membuat dan mengubah ukuran array dinamis.
- Alokasi memori secara eksplisit menggunakan GetMem, FreeMem, Baru, dan Buang ().
- Menggunakan string ANSI / wide / Unicode, varian, antarmuka (dikelola secara otomatis oleh Delphi).
Heap memory tidak memiliki tata letak yang bagus di mana akan ada beberapa pesanan mengalokasikan blok memori. Tumpukan tampak seperti kaleng kelereng. Alokasi memori dari heap adalah acak, satu blok dari sini daripada satu blok dari sana. Dengan demikian, operasi heap sedikit lebih lambat daripada yang ada di stack.
Saat Anda meminta blok memori baru (mis. Membuat instance kelas), manajer memori Delphi akan menangani ini untuk Anda: Anda akan mendapatkan blok memori baru atau yang digunakan dan dibuang.
Tumpukan terdiri dari semua memori virtual (RAM dan ruang disk).
Mengalokasikan Memori Secara Manual
Sekarang karena semua memori sudah jelas, Anda dapat dengan aman (dalam kebanyakan kasus) mengabaikan hal di atas dan hanya melanjutkan menulis program Delphi seperti yang Anda lakukan kemarin.
Tentu saja, Anda harus mengetahui kapan dan bagaimana cara mengalokasikan / membebaskan memori secara manual.
"EStackOverflow" (dari awal artikel) dimunculkan karena dengan setiap panggilan ke DoStackOverflow segmen memori baru telah digunakan dari stack dan stack memiliki keterbatasan. Sesimpel itu.