Catatan
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba masuk atau mengubah direktori.
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba mengubah direktori.
Manajemen memori otomatis adalah salah satu layanan yang disediakan Common Language Runtime selama Eksekusi Terkelola. Pengumpul sampah Common Language Runtime mengelola alokasi dan pelepasan memori untuk aplikasi. Bagi pengembang, ini berarti Anda tidak perlu menulis kode untuk melakukan tugas manajemen memori saat Anda mengembangkan aplikasi terkelola. Manajemen memori otomatis dapat menghilangkan masalah umum, seperti lupa membebaskan objek dan menyebabkan kebocoran memori, atau mencoba mengakses memori untuk objek yang telah dibebaskan. Bagian ini menjelaskan bagaimana pengumpul sampah mengalokasikan dan melepaskan memori.
Mengalokasikan Memori
Saat Anda menginisialisasi proses baru, runtime mencadangkan wilayah ruang alamat yang bersebelahan untuk proses tersebut. Ruang alamat yang dipesan ini disebut memori heap yang dikelola. Tumpukan terkelola mempertahankan penunjuk ke alamat tempat objek berikutnya dalam tumpukan akan dialokasikan. Awalnya, pointer ini diatur ke alamat dasar heap terkelola. Semua jenis referensi dialokasikan pada tumpukan terkelola. Saat aplikasi membuat tipe referensi pertama, memori dialokasikan untuk tipe pada alamat dasar timbunan terkelola. Ketika aplikasi membuat objek berikutnya, pengumpul sampah mengalokasikan memori untuk itu di ruang alamat segera mengikuti objek pertama. Selama ruang alamat tersedia, pengumpul sampah terus mengalokasikan ruang untuk objek baru dengan cara ini.
Mengalokasikan memori dari timbunan terkelola lebih cepat daripada alokasi memori yang tidak dikelola. Karena waktu proses mengalokasikan memori untuk objek dengan menambahkan nilai ke pointer, ini hampir secepat mengalokasikan memori dari stack. Selain itu, karena objek baru yang dialokasikan secara berturut-turut disimpan secara berdampingan dalam tumpukan terkelola, aplikasi dapat mengakses objek dengan sangat cepat.
Melepaskan Memori
Mesin pengoptimal pengumpul sampah menentukan waktu terbaik untuk melakukan pengumpulan berdasarkan alokasi yang dibuat. Ketika pengumpul sampah melakukan koleksi, ia merilis memori untuk objek yang tidak lagi digunakan oleh aplikasi. Ini menentukan objek mana yang tidak lagi digunakan dengan memeriksa akar aplikasi. Setiap aplikasi memiliki sekumpulan akar. Setiap akar mengacu pada objek pada tumpukan terkelola atau diatur menjadi null. Akar aplikasi mencakup bidang statis, variabel lokal, dan parameter pada tumpukan utas, dan daftar CPU. Pengepul sampah memiliki akses ke daftar root aktif yang dipertahankan oleh kompilator just-in-time (JIT) dan runtime. Dengan menggunakan daftar ini, ia memeriksa akar aplikasi, dan dalam prosesnya membuat grafik yang berisi semua objek yang dapat dijangkau dari akar.
Objek yang tidak ada dalam grafik tidak dapat dijangkau dari akar aplikasi. Pengelola sampah menganggap objek yang tidak dapat dijangkau sebagai sampah dan akan melepaskan memori yang telah dialokasikan untuk objek tersebut. Selama pengumpulan, pengumpul sampah memeriksa tumpukan terkelola, mencari blok ruang alamat yang ditempati oleh objek yang tidak dapat dijangkau. Karena menemukan setiap objek yang tidak dapat dijangkau, ia menggunakan fungsi penyalinan memori untuk memampatkan objek yang dapat dijangkau dalam memori, membebaskan blok ruang alamat yang dialokasikan untuk objek yang tidak dapat dijangkau. Setelah memori untuk objek yang dapat dijangkau telah dikompresi, pengumpul sampah membuat koreksi pointer yang diperlukan sehingga akar aplikasi menunjuk ke objek di lokasi baru mereka. Ini juga memposisikan penunjuk tumpukan terkelola setelah objek terakhir yang dapat dijangkau. Perhatikan bahwa memori dipadatkan hanya jika koleksi menemukan sejumlah besar objek yang tidak dapat dijangkau. Jika semua objek dalam tumpukan terkelola bertahan dari koleksi, maka tidak perlu pemadatan memori.
Untuk meningkatkan performa, runtime mengalokasikan memori untuk objek besar dalam heap terpisah. Pengumpul sampah secara otomatis melepaskan memori untuk objek besar. Namun, untuk menghindari memindahkan objek besar dalam memori, memori ini tidak dikompresi.
Generasi dan Performa
Untuk mengoptimalkan performa pengumpul sampah, tumpukan yang dikelola dibagi menjadi tiga generasi: 0, 1, dan 2. Algoritma pengelolaan sampah untuk runtime didasarkan pada beberapa generalisasi yang telah terbukti benar oleh industri perangkat lunak komputer melalui eksperimen dengan berbagai skema pengelolaan sampah. Pertama, lebih cepat untuk memampatkan memori untuk sebagian dari tumpukan terkelola daripada untuk seluruh tumpukan yang dikelola. Kedua, objek yang lebih baru akan memiliki masa pakai yang lebih pendek dan objek yang lebih lama akan memiliki masa pakai yang lebih lama. Terakhir, objek yang lebih baru cenderung terkait satu sama lain dan diakses oleh aplikasi sekitar waktu yang sama.
Pengumpul sampah runtime menyimpan objek baru di generasi 0. Objek yang dibuat di awal siklus hidup aplikasi dan bertahan dari proses pemilahan dipromosikan serta disimpan dalam generasi 1 dan 2. Proses promosi objek dijelaskan nanti dalam topik ini. Karena lebih cepat untuk memampatkan bagian dari tumpukan terkelola daripada seluruh tumpukan, skema ini memungkinkan pengumpul sampah untuk melepaskan memori dalam generasi tertentu daripada melepaskan memori untuk seluruh tumpukan terkelola setiap kali melakukan pengumpulan.
Pada kenyataannya, pengumpul sampah melakukan pengumpulan ketika generasi 0 penuh. Jika aplikasi mencoba membuat objek baru ketika generasi 0 penuh, pengumpul sampah menemukan bahwa tidak ada ruang alamat yang tersisa di generasi 0 untuk mengalokasikan objek. Pengumpul sampah melakukan pengumpulan dalam upaya untuk membebaskan ruang alamat di generasi 0 untuk objek. Pengumpul sampah dimulai dengan memeriksa objek pada generasi 0 daripada semua objek dalam tumpukan terkelola. Ini adalah pendekatan yang paling efisien, karena objek baru cenderung memiliki masa pakai yang pendek, dan diharapkan bahwa banyak objek di generasi 0 tidak akan lagi digunakan oleh aplikasi ketika koleksi dilakukan. Selain itu, koleksi dari generasi 0 sering kali mengumpulkan kembali cukup banyak memori sehingga memungkinkan aplikasi untuk terus membuat objek baru.
Setelah pengumpul sampah melakukan pengumpulan generasi 0, ia memampatkan memori untuk objek yang dapat dijangkau seperti yang dijelaskan dalam Merilis Memori sebelumnya dalam topik ini. Pengumpul sampah kemudian mempromosikan objek-objek ini dan menganggap bagian ini dari tumpukan yang terkelola sebagai generasi 1. Karena objek yang bertahan dari koleksi cenderung memiliki masa pakai yang lebih lama, masuk akal untuk mempromosikannya ke generasi yang lebih tinggi. Akibatnya, pengumpul sampah tidak perlu memeriksa kembali objek dalam generasi 1 dan 2 setiap kali melakukan pengumpulan generasi 0.
Setelah pengumpul sampah melakukan pengumpulan pertama generasi 0 dan mempromosikan objek yang dapat dijangkau ke generasi 1, ia mempertimbangkan sisa tumpukan terkelola generasi 0. Proses ini terus mengalokasikan memori untuk objek baru pada generasi 0 hingga generasi tersebut penuh dan diperlukan pengumpulan lain. Pada titik ini, mesin pengoptimal pengumpul sampah menentukan apakah perlu untuk memeriksa objek pada generasi yang lebih lama. Misalnya, jika kumpulan generasi 0 tidak mengklaim kembali memori yang cukup bagi aplikasi untuk berhasil menyelesaikan upayanya untuk membuat objek baru, pengumpul sampah dapat melakukan koleksi generasi 1, maka generasi 2. Jika ini tidak mengambil kembali memori yang cukup, pengumpul sampah dapat melakukan pengumpulan generasi ke-2, ke-1, dan ke-0. Setelah setiap koleksi, pengumpul sampah memampatkan objek yang dapat dijangkau di generasi 0 dan mempromosikannya ke generasi 1. Objek di generasi 1 yang bertahan koleksi dipromosikan ke generasi 2. Karena pengumpul sampah hanya mendukung tiga generasi, objek pada generasi 2 yang bertahan dari pengumpulan akan tetap berada di generasi 2 sampai mereka tidak dapat dijangkau dalam pengumpulan dimasa depan.
Melepaskan Memori untuk Sumber Daya Tidak Terkelola
Untuk sebagian besar objek yang dibuat aplikasi Anda, Anda dapat mengandalkan pengumpul sampah untuk secara otomatis melakukan tugas manajemen memori yang diperlukan. Namun, sumber daya yang tidak dikelola memerlukan pembersihan eksplisit. Jenis sumber daya yang tidak terkelola yang paling umum adalah objek yang membungkus sumber daya sistem operasi, seperti pegangan file, pegangan jendela, atau koneksi jaringan. Meskipun pengumpul sampah dapat melacak masa pakai objek terkelola yang merangkum sumber daya yang tidak dikelola, ia tidak memiliki pengetahuan khusus tentang cara membersihkan sumber daya. Saat Anda membuat objek yang merangkum sumber daya yang tidak dikelola, disarankan agar Anda memberikan kode yang diperlukan untuk membersihkan sumber daya yang tidak dikelola dalam metode Buang publik. Dengan menyediakan metode Buang , Anda memungkinkan pengguna objek Anda untuk secara eksplisit membebaskan memorinya ketika mereka selesai dengan objek. Ketika Anda menggunakan objek yang merangkum sumber daya yang tidak terkelola, Anda harus menyadari Membuang dan memanggilnya seperlunya. Untuk informasi selengkapnya tentang membersihkan sumber daya yang tidak dikelola dan contoh pola desain untuk menerapkan Buang, lihat Pengumpulan Sampah.