You are currently viewing Memahami Alokasi Stack Dan Heap Dalam Pemrograman C#

Memahami Alokasi Stack Dan Heap Dalam Pemrograman C#

Halo! Selamat datang kembali di “Seri Belajar Dasar Pemrograman Bahasa C#“. Pada materi kali ini kita akan mempelajari dan mencoba memahami bagiamana data-data di dalam suatu variabel disimpan dan dialokasikan ke dalam memori. Kita akan mempelajari dua konsep alokasi memori di C#, yaitu stack dan heap.

Apa Itu Memori Komputer?

Semua aplikasi software menyimpan dan memanipulasi data di dalam memori komputer.

Memori komputer ini berfungsi sama seperti otak manusia, yaitu untuk menyimpan data dan instruksi dari suatu aplikasi komputer.

Ketika kita mendeklarasikan sebuah variabel, sebuah potongan memori akan dialokasikan untuk menyimpan dan memanipulasi nilai dari variabel tersebut. Potongan memori ini akan menyimpan tiga buah informasi, yaitu:

  1. Nama variabel
  2. Tipe data 
  3. Nilai dari variabel tersebut.
stack dan heap - menganalogikan satu potong memori dengan sebuah kardus
Sebuah Kotak Kardus Bisa Kita Anggap Sebagai Satu Potong Memori

Ada dua jenis pengalokasian memori berdasarkan dari tipe data yang disimpan, yaitu alokasi memori stack di mana data akan disimpan dalam alamat memori secara berurutan, serta alokasi memori heap di mana data akan disimpan tanpa mempertimbangkan urutan alamat memorinya.

Untuk mempermudah pemahaman Anda mengenai pengalokasian memori di stack dan heap, Anda bisa membayangkan memori stack seperti sebuah tumpukan kardus dan memori heap seperti sebuah loker.

Apa Itu Alokasi Memori Stack?

Ketika menumpuk sebuah kardus, kita biasanya memulainya dengan menumpuk dari bawah, kemudian menumpuk kardus yang lain di atasnya.

Ketika ingin mengambilnya, kita harus memulainya dari tumpukan paling atas dan seterusnya. Konsep ini dikenal dengan LIFO atau last in first out. Artinya, justru tumpukan terakhir (teratas) yang akan diambil pertama kali.

stack dan heap - tumpukan kardus
Tumpukan Kardus

Stack sendiri dalam Bahasa Indonesia bisa diartikan sebagai suatu benda yang ditumpuk di atas suatu benda yang lain.

Bagaimana Sebuah Variabel Dialokasikan Di Stack?

Memori stack tidak jauh berbeda dengan analogi tumpukan kardus di atas. Setiap variabel yang dideklarasikan dengan tipe data yang termasuk value types,  akan mendapat satu potong memori di stack yang nantinya akan dialokasikan dengan alamat yang berurutan.

Contohnya, apabila kita mendeklarasikan 3 buah variabel di dalam sebuah method, maka ketika method tersebut dipanggil, 3 potong memori di stack akan dialokasikan dengan alamat memori yang berurutan.

static void Main(string[] args)
{
    // Memanggil method
    sebuahMethod();
}

static void sebuahMethod()
{
    // Instansiasi class Mobil / Membuat objek dari class Mobil
    Mobil mobil = new Mobil();
    // Deklarasi dan inisialisasi variabel lokal
    int y = 2, x = 4;
}

Sederhananya, apabila alokasi memori untuk variabel pertama terletak di alamat x100, maka alokasi memori untuk variabel kedua terletak di alamat x101 dan variabel ketiga terletak di alamat x102.

stack dan heap - struktur memori stack
Memori Stack

Melihat Nilai Variabel Di Peta Memori Stack

Pada prakteknya, compiler akan mengalokasikan memori untuk setiap variabel dengan cara yang sedikit berbeda. Mari kita lihat bagaimana sebuah variabel sebenarnya dialokasikan di stack dengan memanfaatkan potongan kode program di bawah ini.

static void Main(string[] args)
{                        
    byte x = 255;
    int y = 8;
    uint z = 4294967295;
}

Pada potongan kode program di atas, kita mendeklarasikan 3 buah variabel dengan tipe data yang berbeda-beda. Yaitu:

  • Tipe data byte yang memiliki ukuran 1 byte,
  • tipe data int yang memiliki ukuran 4 byte,
  • dan terakhir tipe data uint yang memiliki ukuran 4 byte.

(Tabel tipe data dan ukurannya bisa Anda lihat di sini)

Apabila kita melakukan inspeksi pada memori stack, kita akan mendapatkan pemetaan memori seperti di bawah ini.

stack dan heap - alokasi variabel di stack
Peta Memori Stack

Yang perlu kita perhatikan dari gambar di atas adalah:

  • kolom pertama merupakan alamat memori untuk setiap variabel yang disimpan, sedangkan kolom-kolom selanjutnya adalah nilai dari variabel tersebut.
  • Satu kolom memiliki ukuran 1 Byte. Jadi untuk contoh di atas, setiap variabel memiliki alokasi memori sebesar 4 Byte (4 kolom).

Sebentar… bukankah tipe data byte memiliki ukuran 1 Byte. Mengapa variabel yang seharusnya berukuran 1 Byte mendapat alokasi 4 Byte?

Ini terjadi karena kita menggunakan CPU dengan arsitektur x86 atau 32-bit (4 byte). Arsitektur ini memiliki smallest addressable unit atau unit terkecil yang bisa dialamatkan sebesar 4 byte.

stack dan heap - target CPU
Target CPU

Baiklah, sekarang coba kita lihat bagaimana masing-masing variabel di atas dialokasikan di stack.

  1. Pada saat variabel x dengan nilai 255 dialokasikan, nilai variabel tersebut akan disimpan di alamat memori 0x0726E8F4. Meskipun variabel ini sebenarnya hanya berukuran 1 byte, tapi memori yang dialokasikan adalah sebesar 4 byte, yaitu dari 0x0726E8F4 sampai 0x0726E8F7.
  2. Pada saat variabel y dengan nilai 8 dialokasikan, nilai tersebut disimpan di alamat memori 0x0726E8F0 dan mengambil 4 Byte memori dari 0x0726E8F0 sampai 0x0726E8F3.
  3. Terakhir pada saat variabel z dengan nilai 4294967295 (FFFFFFFF jika dinyatakan dengan Hexadesimal) dialokasikan, nilai tersebut disimpan di alamat memori 0x0726E8EC dan mengambil 4 Byte memori dari 0x0726E8EC sampai 0x0726E8EF.

Catatan

Alamat memori yang ditampilkan akan berubah-rubah setiap kali Anda meng-compile aplikasi Anda.

Di sini kita melihat bahwa variabel x menempati alamat memori terbawah (baris ketiga) di stack, lalu variabel y menempati alamat memori di atasnya (baris kedua), dan terakhir variable z yang dideklarasikan terakhir menempati alamat memori teratas di stack (baris pertama).

Apa Itu Memori Heap?

Apabila Anda bisa menganalogikan memori stack seperti tumpukan kardus, sekarang Anda bisa menganalogikan memori heap seperti sebuah loker.

sebuah loker
Loker

Apa yang bisa Anda bayangkan ketika menyimpan sesuatu di dalam loker? 

Benar… Anda bebas menyimpan barang di pintu loker mana saja selama loker tersebut kosong. Pada saat mengambil barang, Anda juga tidak perlu mengeluarkan barang-barang yang disimpan di pintu loker yang lain.

Heap sendiri dalam Bahasa Indonesia kurang lebih juga bisa diartikan sebagai tumpukan. Namun berbeda dengan stack, heap adalah tumpukan yang tidak teratur. Seperti… tumpukan baju kotor (tumpukan baju di lemari bisa dianalogikan sebagai stack).

Ketika kita mendeklarasikan variabel dengan tipe data yang merupakan reference type seperti string, sebenarnya variabel tersebut tetap akan disimpan di stack.

Sebentar.. bukannya reference type disimpan di heap?

Betul! Yang disimpan di heap adalah nilai sebenarnya dari variabel tersebut, sedangkan variabelnya tetap disimpan di stack.

Untuk lebih memahaminya, perhatikan deklarasi variabel di bawah ini.

string str = "Halo";

Pada deklarasi di atas, variabel str akan dialokasikan di stack. Kemudian “Halo” akan disimpan di suatu lokasi di heap. Setelah lokasi teks “Halo” di heap ditentukan, alamat lokasi di mana teks “Halo” disimpan ini lah yang kemudian diberikan ke variabel str. Sehingga, variabel str di stack hanya akan menyimpan alamat lokasi di mana teks “Halo” sebenarnya disimpan. Nilai variabel str di stack merupakan referensi dari nilai variabel str di heap.

Menyimpan nilai dari tipe referensi di heap
Menyimpan Nilai Dari Tipe Referensi Di Heap

Alokasi memori untuk deklarasi variable str di atas, bisa dilihat dari gambar di bawah ini.

Nilai yang sebenarnya disimpan di heap
Bagaimana Nilai “Halo” Disimpan Di Heap

Membebaskan Ruang Memori (Dealokasi)

Setelah data-data yang kita simpan di memori selesai digunakan, data-data tersebut perlu dihapus agar lokasi memori yang diambil bisa dipakai oleh data-data lain yang akan digunakan.

Data-data yang tersimpan di stack akan dihapus secara otomatis setelah method di mana variabel yang menyimpan data-data tersebut selesai dieksekusi.

Untuk lebih memahaminya, perhatikan potongan kode program di bawah ini.

static void Main(string[] args)
{
    SebuahMethod();
}

static void SebuahMethod()
{
    string str = "Halo";
    int x = 255;
} //akhir dari SebuahMethod()

Seperti yang sudah Anda pelajari, baik variabel str maupun x akan dialokasikan di stack ketika SebuahMethod() dipanggil. Setelah method tersebut selesai dieksekusi, maka data-data variabel str dan x di stack akan secara otomatis dihapus. Ruang memori yang tadinya terpakai, kini bebas digunakan kembali untuk kegunaan yang lain.

Masalahnya, nilai str yang tersimpan di stack hanya merupakan alamat di mana nilai str sebenarnya yang disimpan di heap, bukan nilainya itu sendiri. Nilai yang tersimpan di heap tidak akan dihapus secara otomatis meskipun variabel yang menyimpan referensi ke nilai tersebut sudah dihapus.

Sebagai programmer di platform .NET, kita bisa sedikit lega. Kita tidak perlu bingung memikirkan bagaimana caraya melakukan dealokasi memori di heap. Nantinya, Garbage Collector dari .NET akan mengurus semuanya untuk Anda.

Catatan

Pengelolaan memori di C# merupakan topik yang sangat kompleks dan luas. Penjelasan tentang bagaimana garbage collector bekerja berada di luar pembahasan materi kali ini.

Penutup

Pada materi kali ini kita sudah mempelajari tentang bagaimana data-data di dalam sebuah variabel dialokasikan dan disimpan di dalam memori stack dan heap.

Setiap variabel yang dideklarasikan akan disimpan di dalam memori stack. Namun, apabila sebuah variabel mempunyai nilai dari tipe data yang merupakan reference type, maka nilai sebenarnya akan disimpan di memori heap. Sementara nilai variabelnya yang disimpan di stack hanya berisi referensi atau alamat lokasi di mana nilai sebenarnya disimpan.

Data-data yang disimpan di memori stack akan otomatis dihapus ketika method di mana variabel tersebut dideklarasikan telah selesai dieksekusi. Sedangkan Garbage Collector milik .NET akan melakukan dealokasi memori heap.

Apabila Anda mempunyai pertanyaan seputar materi di tulisan ini, silahkan tinggalkan pertanyaan Anda di kolom komentar.

Selamat belajar! 

This Post Has 2 Comments
  1. ady

    Akhirnya paham juga saya. kebetulan lagi belajar assembly. terimakasih.

    1. Dian Nandiwardhana

      Halo Mas Ady,

      Sama-sama, Mas.. Senang materi ini bisa membantu pemahaman Mas Ady..

Tinggalkan Balasan