Pengumpulan sampah Jawa menangani benda mati di tumpukan, tetapi terkadang membekukan dunia. Dalam C ++ saya harus memanggil delete
untuk membuang objek yang dibuat pada akhir siklus hidup itu.
Ini delete
sepertinya harga yang sangat rendah untuk membayar untuk lingkungan yang tidak beku. Menempatkan semua delete
kata kunci yang relevan adalah tugas mekanis. Orang dapat menulis skrip yang akan melakukan perjalanan melalui kode dan menghapus tempat setelah tidak ada cabang baru menggunakan objek tertentu.
Jadi, apa pro dan kontra dari Java build in vs C ++ model diy pengumpulan sampah.
Saya tidak ingin memulai utas C ++ vs Java. Pertanyaan saya berbeda.
Semua hal GC ini - apakah itu bermuara pada "hanya menjadi rapi, jangan lupa untuk menghapus objek yang telah Anda buat - dan Anda tidak akan memerlukan GC khusus? Atau apakah lebih seperti" membuang objek di C ++ benar-benar rumit - saya menghabiskan 20% dari waktu saya untuk itu, namun, kebocoran memori adalah tempat yang umum "?
sumber
new
pergi di konstruktor kelas Anda yang mengelola memori,delete
berjalan di destruktor. Dari sana, semuanya otomatis (penyimpanan). NB bahwa ini bekerja untuk semua jenis sumber daya, bukan hanya memori, tidak seperti pengumpulan sampah. Mutex diambil dalam konstruktor, dirilis dalam destruktor. File dibuka di konstruktor, ditutup di destruktor.Jawaban:
Siklus hidup objek C ++
Jika Anda membuat objek lokal, Anda tidak perlu menghapusnya: kompiler menghasilkan kode untuk menghapusnya secara otomatis ketika objek keluar dari cakupan
Jika Anda menggunakan pointer objek dan membuat objek di toko gratis, maka Anda harus berhati-hati menghapus objek ketika itu tidak lagi diperlukan (seperti yang telah Anda jelaskan). Sayangnya, dalam perangkat lunak yang kompleks, ini mungkin jauh lebih menantang daripada yang terlihat (misalnya bagaimana jika pengecualian muncul dan bagian penghapusan yang diharapkan tidak pernah tercapai?)
Untungnya, dalam C ++ modern (alias C ++ 11 dan yang lebih baru), Anda memiliki pointer cerdas, seperti misalnya
shared_ptr
. Mereka referensi-menghitung objek yang dibuat dengan cara yang sangat efisien, sedikit seperti yang dilakukan pengumpul sampah di Jawa. Dan segera setelah objek tidak lagi direferensikan, aktif terakhirshared_ptr
menghapus objek untuk Anda. Secara otomatis. Seperti pengumpul sampah, tetapi satu objek pada satu waktu dan tanpa penundaan (Ok: Anda perlu perhatian ekstra danweak_ptr
untuk mengatasi referensi melingkar).Kesimpulan: Anda saat ini dapat menulis kode C ++ tanpa harus khawatir tentang alokasi memori, dan yang sama bebasnya dengan GC, tetapi tanpa efek pembekuan.
Siklus hidup objek Java
Yang menyenangkan adalah Anda tidak perlu khawatir tentang siklus hidup objek. Anda cukup membuatnya dan java akan mengurus sisanya. Sebuah GC yang modern akan mengidentifikasi dan menghancurkan benda-benda yang tidak lagi diperlukan (termasuk jika ada referensi melingkar antara objek mati).
Sayangnya, karena kenyamanan ini, Anda tidak dapat mengontrol kapan objek benar-benar dihapus . Secara semantik, penghapusan / penghancuran bertepatan dengan pengumpulan sampah .
Ini sangat bagus jika melihat objek hanya dari segi memori. Kecuali untuk pembekuan, tetapi ini bukan kematian (orang-orang mengerjakan ini). Saya bukan ahli Java, tapi saya pikir penghancuran yang tertunda membuatnya lebih sulit untuk mengidentifikasi kebocoran di java karena referensi sengaja disimpan meskipun objek tidak lagi diperlukan (yaitu Anda tidak dapat benar-benar memantau penghapusan objek).
Tetapi bagaimana jika objek harus mengendalikan sumber daya selain memori, misalnya file terbuka, semafor, layanan sistem? Kelas Anda harus menyediakan metode untuk melepaskan sumber daya ini. Dan Anda akan memiliki tanggung jawab untuk memastikan bahwa metode ini dipanggil ketika sumber daya tidak lagi dibutuhkan. Di setiap jalur percabangan yang mungkin melalui kode Anda, memastikan itu juga dipanggil jika ada pengecualian. Tantangannya sangat mirip dengan penghapusan eksplisit di C ++.
Kesimpulan: GC memecahkan masalah manajemen memori. Tetapi tidak membahas pengelolaan sumber daya sistem lainnya. Tidak adanya penghapusan "tepat waktu" mungkin membuat manajemen sumber daya sangat menantang.
Penghapusan, pengumpulan sampah, dan RAII
Saat Anda bisa mengontrol penghapusan suatu objek dan destruktor yang dipanggil pada penghapusan, Anda bisa memanfaatkan RAII . Pendekatan ini memandang memori hanya sebagai kasus khusus alokasi sumber daya dan menautkan pengelolaan sumber daya lebih aman ke siklus hidup objek, sehingga memastikan penggunaan sumber daya yang dikontrol dengan ketat.
sumber
new
luar konstruktor / pointer pintar, dan jangan pernah gunakan didelete
luar destruktor.Like garbage collector, but one object at a time and without delay (Ok: you need some extra care and weak_ptr to cope with circular references).
Penghitungan referensi dapat mengalir. Misalnya referensi terakhir untukA
pergi, tetapiA
juga memiliki referensi terakhir untukB
, yang memiliki referensi terakhir keC
...And you'll have the responsibility to make sure that this method is called when the resources are no longer needed. In every possible branching path through your code, ensuring it is also invoked in case of exceptions.
Java dan C # memiliki pernyataan blok khusus untuk ini.Jika Anda dapat menulis skrip seperti itu, selamat. Anda adalah pengembang yang lebih baik daripada saya. Sejauh ini.
Satu-satunya cara Anda benar-benar dapat menghindari kebocoran memori dalam kasus-kasus praktis adalah standar pengkodean yang sangat ketat dengan aturan yang sangat ketat yang merupakan pemilik suatu objek, dan kapan benda itu dapat dan harus dilepaskan, atau alat seperti smart pointer yang menghitung referensi ke objek dan menghapus keberatan ketika referensi terakhir hilang.
sumber
Jika Anda menulis kode C ++ yang benar dengan RAII, Anda biasanya tidak menulis yang baru atau menghapus. Satu-satunya "baru" yang Anda tulis ada di dalam pointer bersama sehingga Anda benar-benar tidak perlu menggunakan "hapus".
sumber
new
sama sekali, bahkan dengan pointer bersama - Anda harus menggunakanstd::make_shared
sebagai gantinya.make_unique
,. Sangat jarang Anda benar-benar membutuhkan kepemilikan bersama.Membuat hidup programmer lebih mudah dan mencegah kebocoran memori adalah keuntungan penting dari pengumpulan sampah tetapi tidak hanya satu. Lain adalah mencegah fragmentasi memori. Di C ++, setelah Anda mengalokasikan objek menggunakan
new
kata kunci, itu tetap dalam posisi tetap dalam memori. Ini berarti bahwa, ketika aplikasi berjalan, Anda pada akhirnya memiliki celah kehabisan memori di antara objek yang dialokasikan. Jadi mengalokasikan memori dalam C ++ harus menjadi proses yang lebih rumit, karena sistem operasi harus dapat menemukan blok yang tidak terisi dengan ukuran yang sesuai antara celah.Pengumpulan sampah mengatasinya dengan mengambil semua objek yang tidak dihapus dan menggesernya dalam memori sehingga mereka membentuk blok yang berkelanjutan. Jika Anda merasa bahwa pengumpulan sampah memerlukan waktu, itu mungkin karena proses ini, bukan karena alokasi memori itu sendiri. Manfaatnya adalah bahwa ketika datang ke alokasi memori, itu hampir sama mudahnya dengan menggeser pointer ke ujung tumpukan.
Jadi, dalam C ++ menghapus objek cepat tetapi membuatnya bisa lambat. Di Jawa membuat objek tidak membutuhkan waktu sama sekali tetapi Anda perlu melakukan pembersihan rumah sesekali.
sumber
Janji-janji utama Jawa adalah
Sepertinya Java menjamin Anda bahwa sampah akan dibuang (tidak harus dengan cara yang efisien). Jika Anda menggunakan C / C ++ Anda memiliki kebebasan dan tanggung jawab. Anda bisa melakukannya lebih baik daripada GC Java, atau Anda bisa jauh lebih buruk (lewati
delete
semua bersama dan memiliki masalah kebocoran memori).Jika Anda memerlukan kode yang "memenuhi standar kualitas tertentu" dan untuk mengoptimalkan "rasio harga / kualitas" gunakan Java. Jika Anda siap untuk berinvestasi sumber daya tambahan (waktu ahli Anda) untuk meningkatkan kinerja aplikasi kritis misi - gunakan C.
sumber
Perbedaan besar yang dihasilkan pengumpulan sampah adalah Anda tidak perlu menghapus objek secara eksplisit. Perbedaan yang jauh lebih besar adalah Anda tidak perlu menyalin objek.
Ini memiliki efek yang meresap dalam merancang program dan antarmuka secara umum. Izinkan saya memberikan satu contoh kecil untuk menunjukkan seberapa jauh jangkauannya.
Di Jawa, ketika Anda mengeluarkan sesuatu dari tumpukan, nilai yang muncul dikembalikan, sehingga Anda mendapatkan kode seperti ini:
Di Jawa, ini adalah pengecualian aman, karena semua yang kita lakukan sebenarnya adalah menyalin referensi ke objek, yang dijamin terjadi tanpa pengecualian. Hal yang sama tidak benar dalam C ++. Dalam C ++, mengembalikan nilai berarti (atau setidaknya bisa berarti) menyalin nilai itu, dan dengan beberapa jenis yang bisa melempar pengecualian. Jika pengecualian dilemparkan setelah item telah dihapus dari tumpukan, tetapi sebelum salinan sampai ke penerima, item telah bocor. Untuk mencegahnya, tumpukan C ++ menggunakan pendekatan yang agak klumsier di mana mengambil item teratas dan menghapus item teratas adalah dua operasi terpisah:
Jika pernyataan pertama melempar pengecualian, yang kedua tidak akan dieksekusi, jadi jika pengecualian dilemparkan dalam penyalinan, item tersebut tetap berada di tumpukan seolah-olah tidak ada yang terjadi sama sekali.
Masalah yang jelas adalah bahwa ini hanya canggung dan (bagi orang yang belum menggunakannya) tidak terduga.
Hal yang sama berlaku di banyak bagian lain dari C ++: terutama dalam kode generik, keamanan pengecualian meliputi banyak bagian desain - dan ini sebagian besar disebabkan oleh fakta bahwa paling tidak paling berpotensi melibatkan penyalinan objek (yang mungkin dibuang), di mana Java hanya akan membuat referensi baru ke objek yang sudah ada (yang tidak bisa melempar, jadi kita tidak perlu khawatir tentang pengecualian).
Sejauh skrip sederhana untuk disisipkan di
delete
mana diperlukan: jika Anda dapat secara statis menentukan kapan harus menghapus item berdasarkan struktur kode sumber, mungkin seharusnya tidak menggunakannew
dandelete
di tempat pertama.Biarkan saya memberi Anda contoh program yang hampir pasti tidak mungkin: sistem untuk panggilan, pelacakan, penagihan (dll) panggilan telepon. Ketika Anda memanggil ponsel Anda, itu menciptakan objek "panggilan". Objek panggilan melacak siapa yang Anda panggil, berapa lama Anda berbicara dengan mereka, dll., Untuk menambahkan catatan yang sesuai ke log penagihan. Objek panggilan memonitor status perangkat keras, jadi ketika Anda menutup telepon, itu menghancurkan dirinya sendiri (menggunakan yang banyak dibahas
delete this;
). Hanya saja, itu tidak terlalu sepele seperti "ketika Anda menutup telepon". Misalnya, Anda dapat melakukan panggilan konferensi, menghubungkan dua orang, dan menutup telepon - tetapi panggilan tersebut berlanjut di antara kedua pihak bahkan setelah Anda menutup telepon (tetapi tagihan dapat berubah).sumber
Sesuatu yang saya pikir tidak disebutkan di sini adalah bahwa ada efisiensi yang berasal dari pengumpulan sampah. Dalam kolektor Java yang paling umum digunakan, tempat utama objek dialokasikan adalah area yang disediakan untuk kolektor penyalinan. Ketika hal-hal mulai, ruang ini kosong. Ketika objek dibuat, mereka dialokasikan bersebelahan di ruang terbuka yang besar sampai tidak dapat mengalokasikan satu di ruang bersebelahan yang tersisa. GC menendang dan mencari benda di ruang ini yang tidak mati. Ini menyalin objek hidup ke daerah lain dan menyatukannya (yaitu tidak ada fragmentasi.) Ruang lama dianggap bersih. Kemudian terus mengalokasikan objek bersama-sama dan mengulangi proses ini sesuai kebutuhan.
Ada dua manfaatnya. Yang pertama adalah tidak ada waktu dihabiskan untuk menghapus objek yang tidak digunakan. Setelah benda hidup disalin, batu tulis dianggap bersih dan benda mati hanya dilupakan. Dalam banyak aplikasi, sebagian besar objek tidak berumur panjang sehingga biaya menyalin set hidup lebih murah dibandingkan dengan penghematan yang diperoleh dengan tidak perlu khawatir tentang set mati.
Manfaat kedua adalah ketika objek baru dialokasikan, tidak perlu mencari area yang berdekatan. VM selalu tahu di mana objek berikutnya akan ditempatkan (peringatan: concurrency diabaikan disederhanakan.)
Pengumpulan dan alokasi semacam ini sangat cepat. Dari perspektif throughput keseluruhan, sulit dikalahkan untuk banyak skenario. Masalahnya adalah beberapa objek akan hidup lebih lama dari yang Anda inginkan untuk terus menyalinnya dan pada akhirnya itu berarti kolektor mungkin perlu berhenti untuk waktu yang signifikan setiap sesekali dan kapan itu akan terjadi dapat diprediksi. Tergantung pada panjang jeda dan jenis aplikasi, ini mungkin atau mungkin tidak menjadi masalah. Setidaknya ada satu kolektor yang tidak ada jeda . Saya berharap ada beberapa tradeoff efisiensi yang lebih rendah untuk mendapatkan sifat yang tanpa jeda, tetapi salah satu orang yang mendirikan perusahaan itu (Gil Tene) adalah ahli di GC dan presentasinya adalah sumber informasi hebat tentang GC.
sumber
Dalam pengalaman pribadi saya di C ++ dan bahkan C, kebocoran memori tidak pernah sulit untuk dihindari. Dengan prosedur pengujian yang waras dan Valgrind, misalnya, setiap kebocoran fisik yang disebabkan oleh panggilan
operator new/malloc
tanpa sambungandelete/free
sering terdeteksi dan diperbaiki dengan cepat. Agar adil beberapa kode C besar atau sekolah tua C ++ mungkin sangat mungkin memiliki beberapa kasus tepi yang tidak jelas yang mungkin secara fisik membocorkan beberapa byte memori di sana-sini sebagai akibat dari tidakdeleting/freeing
dalam kasus tepi yang terbang di bawah radar pengujian.Namun sejauh pengamatan praktis, aplikasi terlemah yang saya temui (seperti pada yang mengkonsumsi lebih banyak dan lebih banyak memori semakin lama Anda menjalankannya, meskipun jumlah data yang kami kerjakan tidak bertambah) biasanya tidak ditulis dalam C atau C ++. Saya tidak menemukan hal-hal seperti Linux Kernel atau Unreal Engine atau bahkan kode asli yang digunakan untuk mengimplementasikan Java di antara daftar perangkat lunak bocor yang saya temui.
Jenis perangkat lunak bocor yang paling menonjol yang cenderung saya temui adalah hal-hal seperti applet Flash, seperti game Flash, meskipun mereka menggunakan pengumpulan sampah. Dan itu bukan perbandingan yang adil jika seseorang menyimpulkan sesuatu dari ini karena banyak aplikasi Flash ditulis oleh pengembang pemula yang mungkin kurang memiliki prinsip-prinsip rekayasa suara dan prosedur pengujian (dan juga saya yakin ada profesional yang terampil di luar sana yang bekerja dengan GC yang jangan berjuang dengan perangkat lunak yang bocor), tetapi saya ingin mengatakan banyak hal kepada siapa pun yang berpikir GC mencegah perangkat lunak yang bocor ditulis.
Pointer Menggantung
Sekarang datang dari domain khusus saya, pengalaman, dan sebagai salah satu yang sebagian besar menggunakan C dan C ++ (dan saya berharap manfaat GC akan bervariasi tergantung pada pengalaman dan kebutuhan kami), hal yang paling langsung diselesaikan GC bagi saya bukanlah masalah kebocoran memori praktis tetapi Menggantung akses pointer, dan itu benar-benar bisa menjadi penyelamat dalam skenario misi-kritis.
Sayangnya dalam banyak kasus di mana GC memecahkan apa yang seharusnya menjadi akses pointer menggantung, itu menggantikan kesalahan programmer yang sama dengan kebocoran memori logis.
Jika Anda membayangkan game Flash yang ditulis oleh pembuat kode pemula, ia mungkin menyimpan referensi ke elemen-elemen game dalam beberapa struktur data, membuatnya berbagi kepemilikan atas sumber daya game ini. Sayangnya, katakanlah dia membuat kesalahan di mana dia lupa untuk menghapus elemen-elemen game dari salah satu struktur data setelah maju ke tahap berikutnya, mencegah mereka dibebaskan sampai seluruh game ditutup. Namun, gim ini tetap berfungsi dengan baik karena elemen-elemennya tidak digambar atau memengaruhi interaksi pengguna. Namun demikian, gim ini mulai menggunakan lebih banyak dan lebih banyak memori sementara laju bingkai bekerja sendiri untuk tayangan slide, sementara pemrosesan tersembunyi masih berulang melalui kumpulan elemen tersembunyi dalam gim ini (yang kini telah menjadi sangat besar ukurannya). Ini adalah jenis masalah yang sering saya temui dalam game Flash tersebut.
Sekarang katakanlah pengembang pemula yang sama menulis game di C ++. Dalam hal itu biasanya hanya akan ada satu struktur data pusat dalam game yang "memiliki" memori sementara yang lain menunjuk ke memori itu. Jika dia membuat kesalahan yang sama, kemungkinannya adalah bahwa, setelah maju ke tahap berikutnya, permainan akan crash sebagai akibat dari mengakses pointer menggantung (atau lebih buruk, melakukan sesuatu selain crash).
Ini adalah jenis trade-off paling cepat yang cenderung saya temui di domain saya paling sering antara GC dan tidak ada GC. Dan saya sebenarnya tidak terlalu peduli dengan GC di domain saya, yang tidak terlalu kritis terhadap misi, karena pergulatan terbesar yang pernah saya miliki dengan perangkat lunak bocor melibatkan penggunaan GC secara serampangan di sebuah tim sebelumnya yang menyebabkan kebocoran yang dijelaskan di atas. .
Dalam domain khusus saya, saya sebenarnya lebih suka perangkat lunak crash atau glitching dalam banyak kasus karena itu setidaknya jauh lebih mudah untuk dideteksi daripada mencoba melacak mengapa perangkat lunak secara misterius mengkonsumsi jumlah memori eksplosif setelah menjalankannya selama setengah jam sementara semua dari kami tes unit dan integrasi lulus tanpa keluhan (bahkan dari Valgrind, karena memori dibebaskan oleh GC saat dimatikan). Namun itu bukan slam pada GC di pihak saya atau upaya untuk mengatakan bahwa itu tidak berguna atau semacamnya, tapi itu belum ada peluru perak, bahkan tidak dekat, dalam tim saya bekerja dengan perangkat lunak bocor (untuk sebaliknya saya memiliki pengalaman yang berlawanan dengan satu basis kode yang menggunakan GC menjadi yang paling lemah yang pernah saya temui). Agar adil, banyak anggota di tim itu bahkan tidak tahu apa itu referensi yang lemah,
Kepemilikan dan Psikologi Bersama
Masalah yang saya temukan dengan pengumpulan sampah yang membuatnya sangat rentan terhadap "kebocoran memori" (dan saya akan bersikeras menyebutnya sebagai 'kebocoran ruang' berperilaku dengan cara yang sama persis dari perspektif pengguna-akhir) di tangan mereka yang tidak menggunakannya dengan hati-hati berhubungan dengan "kecenderungan manusia" sampai tingkat tertentu dalam pengalaman saya. Masalah dengan tim itu dan basis kode paling sedikit yang pernah saya temui adalah bahwa mereka tampaknya berada di bawah kesan bahwa GC akan memungkinkan mereka untuk berhenti memikirkan siapa yang memiliki sumber daya.
Dalam kasus kami, kami memiliki begitu banyak objek yang saling rujukan. Model akan merujuk bahan bersama dengan perpustakaan bahan dan sistem shader. Bahan akan referensi tekstur bersama dengan pustaka tekstur dan shader tertentu. Kamera akan menyimpan referensi ke semua jenis entitas adegan yang harus dikecualikan dari rendering. Daftar itu kelihatannya berlanjut tanpa batas. Itu membuat hampir semua sumber daya yang lumayan dalam sistem yang dimiliki dan diperpanjang seumur hidup di 10+ tempat lain di negara aplikasi sekaligus, dan itu sangat, sangat rentan terhadap kesalahan manusia dari jenis yang akan diterjemahkan menjadi kebocoran (dan tidak yang minor, saya berbicara gigabyte dalam hitungan menit dengan masalah kegunaan yang serius). Secara konseptual semua sumber daya ini tidak perlu dibagi dalam kepemilikan, mereka semua secara konseptual memiliki satu pemilik,
Jika kita berhenti berpikir tentang siapa yang memiliki memori apa, dan dengan senang hati hanya menyimpan referensi seumur hidup untuk objek di seluruh tempat tanpa memikirkan hal ini, maka perangkat lunak tidak akan crash sebagai akibat dari pointer yang menggantung tetapi hampir pasti, di bawah suatu pola pikir yang ceroboh, mulailah membocorkan ingatan seperti orang gila dengan cara yang sangat sulit dilacak dan akan lolos dari ujian.
Jika ada satu manfaat praktis untuk penunjuk menggantung di domain saya, itu menyebabkan gangguan dan crash yang sangat buruk. Dan itu cenderung setidaknya memberikan pengembang insentif, jika mereka ingin mengirimkan sesuatu yang dapat diandalkan, untuk mulai berpikir tentang manajemen sumber daya dan melakukan hal-hal yang diperlukan yang diperlukan untuk menghapus semua referensi tambahan / pointer ke objek yang tidak lagi dibutuhkan secara konseptual.
Manajemen Sumber Daya Aplikasi
Manajemen sumber daya yang tepat adalah nama permainan jika kita berbicara tentang menghindari kebocoran dalam aplikasi yang berumur panjang dengan keadaan terus-menerus disimpan di mana kebocoran akan menimbulkan frame rate yang serius dan masalah kegunaan. Dan mengelola sumber daya dengan benar di sini tidak kalah sulit dengan atau tanpa GC. Karya ini tidak kurang manual baik cara untuk menghapus referensi yang sesuai untuk objek tidak lagi diperlukan apakah itu pointer atau referensi yang memperpanjang seumur hidup.
Itulah tantangan di domain saya, tidak lupa dengan
delete
apa yang kaminew
(kecuali kami berbicara jam amatir dengan pengujian, praktik, dan alat jelek). Dan itu membutuhkan pemikiran dan kepedulian apakah kita menggunakan GC atau tidak.Multithreading
Satu masalah lain yang saya temukan sangat berguna dengan GC, jika bisa digunakan dengan sangat hati-hati dalam domain saya, adalah menyederhanakan manajemen sumber daya dalam konteks multithreading. Jika kami berhati-hati untuk tidak menyimpan referensi perpanjangan sumber daya seumur hidup di lebih dari satu tempat dalam status aplikasi, maka sifat referensi GC yang diperluas seumur hidup bisa sangat berguna sebagai cara untuk utas untuk sementara memperluas sumber daya yang sedang diakses untuk memperluas masa pakainya hanya untuk durasi yang singkat seperti yang diperlukan agar utas selesai memprosesnya.
Saya pikir sangat hati-hati menggunakan GC dengan cara ini dapat menghasilkan sangat, perangkat lunak yang tidak bocor, sementara secara bersamaan menyederhanakan multithreading.
Ada beberapa cara untuk mengatasi hal ini meskipun tidak ada GC. Dalam kasus saya, kami menyatukan representasi entitas adegan perangkat lunak, dengan utas yang sementara menyebabkan sumber daya adegan diperpanjang untuk jangka waktu singkat dengan cara yang agak umum sebelum fase pembersihan. Ini mungkin sedikit berbau seperti GC tetapi perbedaannya adalah bahwa tidak ada "kepemilikan bersama" yang terlibat, hanya desain pemrosesan adegan yang seragam dalam utas yang menunda penghancuran sumber daya tersebut. Masih akan jauh lebih mudah untuk hanya mengandalkan GC di sini jika itu dapat digunakan dengan sangat hati-hati dengan pengembang yang teliti, hati-hati untuk menggunakan referensi yang lemah di area persisten yang relevan, untuk kasus multithreading tersebut.
C ++
Akhirnya:
Di Modern C ++, ini umumnya bukan sesuatu yang harus Anda lakukan secara manual. Bahkan tidak banyak tentang lupa melakukannya. Ketika Anda melibatkan penanganan pengecualian ke dalam gambar, maka bahkan jika Anda menulis korespondensi di
delete
bawah beberapa panggilan untuknew
, sesuatu bisa melempar di tengah dan tidak pernah mencapaidelete
panggilan jika Anda tidak bergantung pada panggilan destruktor otomatis yang dimasukkan oleh kompiler untuk melakukan ini untuk kamu.Dengan C ++ yang secara praktis Anda perlukan, kecuali jika Anda bekerja seperti konteks yang disematkan dengan pengecualian dan pustaka khusus yang sengaja diprogram untuk tidak membuang, hindari pembersihan sumber daya manual seperti itu (yang termasuk menghindari panggilan manual untuk membuka kunci di luar di luar dokumen. , misalnya, dan bukan hanya alokasi memori). Penanganan pengecualian cukup banyak menuntutnya, sehingga semua pembersihan sumber daya harus otomatis melalui destruktor untuk sebagian besar.
sumber