Apakah referensi menghitung GC vs. melacak GC properti bahasa atau properti implementasi?

9

Kami kadang-kadang mendengar "Swift tidak melakukan klasik (melacak) GC, itu menggunakan ARC."

Tetapi saya tidak yakin apakah ada sesuatu dalam semantik Swift yang memerlukan penghitungan referensi. Tampaknya seseorang dapat membangun kompiler dan runtime Swift sendiri untuk menggunakan tracing GC.

Jadi apa sebenarnya "referensi-dihitung" tentang Swift? Implementasi Apple atau bahasanya sendiri? Apakah ada bagian dari bahasa atau perpustakaan yang sangat mendukung ARC sehingga kita dapat menggunakan label itu untuk bahasa itu sendiri?

Ray Toal
sumber

Jawaban:

9

Swift menjamin bahwa setelah referensi terakhir ke suatu objek dijatuhkan, objek tersebut akan diinisialisasi, dan deinitkode segera dijalankan.

Memperoleh jaminan semacam ini melalui GC tidak mungkin - setidaknya, bukan tanpa mengorbankan kinerja. Mekanisme GC standar hanya memastikan deinitkode pada akhirnya dijalankan, misalnya pada siklus GC berikutnya. Untuk semantik yang tepat, Anda perlu penghitungan referensi di suatu tempat.

chi
sumber
3
Ah, jadi kehadiran deinitsebagai kata kunci dan semantik terkaitnya memang hal-hal yang menempatkan penghitungan referensi tepat dalam bahasa, bukan implementasi, ranah.
Ray Toal
2
Tidak ada yang mencegah runtime GCed untuk memeriksa objek yang tidak dapat dijangkau kapan pun ada sesuatu yang tidak dapat dialokasikan. Itu hanya sangat tidak efisien.
Raphael
@ Raphael Diedit untuk lebih tepatnya pada titik itu.
chi
3

chi telah menjawab pertanyaan spesifik dalam tubuh tentang cepat, jawaban ini menjawab pertanyaan yang lebih umum dalam judul.

Apakah referensi menghitung GC vs. melacak GC properti bahasa atau properti implementasi?

penghitungan referensi GC dan penelusuran GC memberi para programmer berbagai jaminan.

Penghitungan referensi memberikan determinisme di lokasi dalam aliran program di mana objek dihancurkan, yang dapat menjadi penting jika objek memiliki sumber daya yang langka yang harus dibebaskan dengan cepat. Di sisi lain itu tidak dapat berurusan dengan siklus referensi "kuat".

Terserah spesifikasi bahasa individu bagaimana jika ada karakteristik yang dijamin dan karenanya pilihan mana yang tersedia untuk implementasi yang sesuai.

Peter Green
sumber
4
Dimungkinkan juga untuk menggabungkan refcount dan GC. Kemudian bahasa dapat mendokumentasikan bahwa objek memiliki destruktor mereka dieksekusi segera setelah mereka tidak direferensikan (menyiratkan refcount dalam satu atau lain bentuk) dan bahwa siklus referensi akan dihancurkan pada akhirnya (menyiratkan beberapa bentuk GC). Atau, implementasi bisa melakukan ini sementara bahasa tidak menjamin ketika destruktor dijalankan (IIRC itu kasus Python dan implementasi rujukannya), dalam hal ini akan menjadi properti implementasi.
Gilles 'SANGAT berhenti menjadi jahat'
1

Anda bisa menggunakan bahasa yang dikenal sebagai Swift dan ganti namanya menjadi "Swift with ARC". Anda kemudian dapat membuat bahasa baru bernama "Swift with GC" dengan sintaksis yang persis sama, tetapi dengan lebih sedikit jaminan tentang kapan objek-objek dideallocated.

Di Swift with ARC, begitu jumlah referensi adalah 0, objek akan hilang. Dengan pengumpulan sampah, selama Anda memiliki referensi yang lemah, Anda bisa menetapkan referensi yang lemah itu ke referensi yang kuat untuk "memulihkan" objek. (Dalam Swift, begitu jumlah referensi adalah 0, referensi lemah adalah nihil); itu perbedaan utama.

Dan tentu saja Swift dengan ARC menjamin bahwa membunuh jumlah referensi terakhir akan segera membatalkan alokasi objek. Misalnya, Anda mungkin memiliki kelas FileWriter, di mana Anda tidak diizinkan memiliki dua instance menulis ke file yang sama ada pada saat yang sama. Di Swift dengan ARC Anda bisa mengatakan oldWriter = nil; newWriter = FileWriter (...) dan Anda akan tahu bahwa FileWriter baru hanya dibuat setelah yang lama dihapus (kecuali Anda menyimpan referensi lain di sekitar); di Swift dengan GC ini tidak akan berhasil.

Perbedaan lain adalah bahwa dalam "Swift with ARC", objek yang hanya direferensikan melalui siklus referensi yang kuat, tetapi tidak benar-benar dapat dijangkau, dijamin tidak dapat dialokasikan.

gnasher729
sumber