Singkatnya : Pengumpul sampah tidak menggunakan rekursi. Mereka hanya mengontrol pelacakan dengan melacak dua set dasarnya (yang dapat menggabungkan). Urutan penelusuran dan pemrosesan sel tidak relevan, yang memberikan kebebasan implementasi yang cukup besar untuk mewakili set. Karenanya ada banyak solusi yang sebenarnya sangat murah dalam penggunaan memori. Ini penting karena GC disebut tepat ketika tumpukan kehabisan memori. Hal-hal agak berbeda dengan memori virtual besar, karena halaman baru dapat dengan mudah dialokasikan, dan musuh bukanlah kekurangan ruang, tetapi kurangnya data
lokalitas .
Saya berasumsi Anda sedang mempertimbangkan melacak pemulung, bukan penghitungan referensi yang tampaknya tidak berlaku untuk pertanyaan Anda.
Pertanyaannya adalah fokus pada biaya memori pelacakan untuk melacak satu set: set (untuk yang tidak dilacak) dari sel memori yang dapat diakses yang masih mengandung pointer yang belum dilacak. Ini hanya setengah dari masalah memori
untuk pengumpulan sampah. GC juga harus melacak set lain: set (untuk dikunjungi) dari semua sel yang telah ditemukan dapat diakses, sehingga dapat mengklaim kembali semua sel lain di akhir proses. Membahas satu dan bukan yang lain masuk akal terbatas, karena mereka mungkin memiliki biaya yang sama, menggunakan solusi yang sama, dan bahkan digabungkan.VUV
Hal pertama yang perlu diperhatikan adalah bahwa semua pelacakan GC mengikuti model abstrak yang sama, berdasarkan eksplorasi sistematis dari sel-sel yang diarahkan dalam memori yang dapat diakses dari program, di mana sel-sel memori adalah simpul dan pointer adalah tepi yang diarahkan. Ini digunakan untuk set berikut:
himpunan (dikunjungi) dari sel-sel yang sudah ditemukan dapat diakses oleh mutator , yaitu program atau algoritma untuk mana GC dilakukan. Himpunan dipartisi menjadi dua himpunan bagian terpisah:
;V V = U ∪ TVVV=U∪T
set (tidak terlacak) dari sel yang dikunjungi dengan pointer yang belum diikuti;U
set (dilacak) dari sel-sel yang dikunjungi yang memiliki semua pointer mereka dilacak.T
kami juga mencatat himpunan semua sel dalam tumpukan, apakah digunakan atau tidak.H
Hanya dan , atau dan , yang perlu diwakili, agar algoritma bekerja.U U TVUUT
Algoritme dimulai dari beberapa root pointer yang dikenal dengan sistem run-time (biasanya pointer dalam memori yang dialokasikan stack), dan menempatkan semua sel yang mereka tunjuk dalam set tidak dilacak (maka dalam juga).VUV
Kemudian kolektor mengambil sel dalam satu per satu, dan memeriksa setiap sel semua petunjuknya. Untuk setiap pointer, jika sel runcing berada di , maka tidak ada yang dilakukan, selain itu sel runcing ditambahkan ke , karena penunjuknya belum diperiksa. Ketika semua pointer yang telah diproses, sel ditransfer dari set untraced ke set ditelusuri .c V U c U TUcVUcUT
Pelacakan berakhir ketika kosong. Ini pasti terjadi, karena tidak ada sel yang melewati lebih dari sekali. Pada titik itu, , dan semua sel dalam diketahui dapat diakses oleh program, sehingga tidak dapat direklamasi. Komplemen dari di heap menentukan sel-sel apa yang tidak dapat dijangkau oleh program mutator dan dapat direklamasi oleh kolektor untuk alokasi masa depan ke mutator.U V = T V H - V VUUV=TVH−VV
Tentu saja, detailnya bervariasi tergantung pada bagaimana set diimplementasikan, dan apakah itu dan , atau dan , yang diwakili secara efektif.U U TVUUT
Saya juga melewatkan detail tentang apa itu sel, apakah mereka datang dalam satu ukuran atau banyak, bagaimana kita menemukan pointer di dalamnya, bagaimana mereka dapat dipadatkan, dan sejumlah masalah teknis lainnya yang dapat Anda temukan dalam buku dan survei tentang pengumpulan sampah .
Anda mungkin memperhatikan bahwa ini adalah algoritma yang sangat sederhana. Tidak ada rekursi, tetapi hanya satu lingkaran pada elemen-elemen himpunan yang dapat tumbuh saat sedang diprosesU , sampai akhirnya kosong. Tidak ada asumsi apriori tentang memori tambahan.
Apa pun yang memungkinkan mengidentifikasi set, dan melakukan cukup murah operasi yang diperlukan akan dilakukan. Perhatikan bahwa urutan pemrosesan sel tidak relevan (tidak perlu tumpukan pushdown), yang memberikan banyak kebebasan untuk memilih cara untuk mewakili set secara efisien.
Dimana implementasi yang dikenal berbeda dalam cara set ini sebenarnya diwakili. Banyak teknik yang sebenarnya telah digunakan:
bit map: Beberapa ruang memori disimpan untuk peta yang memiliki satu bit untuk setiap sel memori, yang dapat ditemukan menggunakan alamat sel. Bit aktif ketika sel yang sesuai berada di set yang ditentukan oleh peta. Jika hanya peta bit yang digunakan, Anda hanya perlu 2 bit per sel.
sebagai alternatif, Anda mungkin memiliki ruang untuk bit tag khusus (atau 2) di setiap sel untuk menandainya.
log2pp
Anda dapat menguji predikat pada konten sel, dan petunjuknya.
Anda dapat memindahkan sel di bagian memori bebas yang ditujukan untuk semua sel yang hanya dimiliki oleh perangkat yang diwakili.
VTTU
Anda sebenarnya dapat menggabungkan teknik-teknik ini, bahkan untuk satu set tunggal.
Seperti yang dikatakan, semua hal di atas telah digunakan oleh beberapa pengumpul sampah yang diimplementasikan, aneh karena beberapa mungkin terlihat. Itu semua tergantung pada berbagai kendala implementasi. Dan mereka bisa agak murah dalam penggunaan memori, mungkin dibantu dengan memproses kebijakan pesanan yang dapat dipilih secara bebas untuk tujuan itu, karena mereka tidak masalah untuk hasil akhirnya.
Apa yang mungkin tampak paling aneh, mentransfer sel di area baru, sebenarnya sangat umum: ini disebut kumpulan salinan. Sebagian besar digunakan dengan memori virtual.
Jelas tidak ada rekursi, dan tumpukan algoritma mutator tidak harus digunakan.
Poin penting lainnya adalah banyak GC modern diterapkan untuk memori virtual besar . Maka mendapatkan ruang untuk mengimplementasikan dan daftar atau tumpukan tambahan tidak menjadi masalah karena halaman baru dapat dengan mudah dialokasikan. Namun, dalam ingatan virtual yang besar, musuh bukanlah kekurangan ruang tetapi kurangnya lokalitas . Kemudian, struktur yang mewakili set, dan penggunaannya, harus diarahkan untuk melestarikan lokalitas struktur data dan pelaksanaan GC. Masalahnya bukan ruang tetapi waktu. Implementasi yang tidak memadai lebih cenderung menunjukkan perlambatan yang tidak dapat diterima daripada limpahan memori.
Saya tidak memberikan referensi ke banyak algoritma spesifik, yang dihasilkan dari berbagai kombinasi teknik ini, karena ini tampaknya cukup lama.