"Hai! Saya memutuskan untuk memberi satu lagi pelajaran kecil tentang kutipan sampah."
Seperti yang anda sedia maklum, mesin Java itu sendiri memantau apabila objek menjadi tidak diperlukan, dan memadamkannya.
"Yep. Awak dengan Rishi dah beritahu saya tadi. Saya tak ingat butirannya."
"OK. Kalau begitu mari kita sambung semula."
"Sebaik sahaja objek dicipta, JVM memperuntukkan memori untuknya. Minat terhadap objek dipantau menggunakan pembolehubah rujukan. Objek boleh dipadam semasa pengumpulan sampah, iaitu prosedur di mana memori dikeluarkan jika tiada pembolehubah merujuk objek. "
"Beritahu saya sedikit tentang pemungut sampah—apa itu dan cara ia berfungsi."
"OK. Pengumpulan sampah pernah berlaku pada utas utama. Setiap 5 minit, atau lebih kerap. Jika ingatan kosong tidak mencukupi, mesin Java akan menggantung semua utas dan memadam objek yang tidak digunakan."
"Tetapi pendekatan ini telah ditinggalkan sekarang. Pengumpul sampah generasi seterusnya berfungsi di belakang tabir dan pada benang yang berasingan. Ini dipanggil pengumpulan sampah serentak."
"Saya faham. Bagaimana sebenarnya keputusan untuk memadam objek atau tidak dibuat?"
"Hanya mengira bilangan rujukan kepada objek tidak begitu berkesan—mungkin terdapat objek yang merujuk antara satu sama lain, tetapi tidak dirujuk oleh objek lain."
"Jadi Java mengambil pendekatan yang berbeza. Java membahagikan objek kepada boleh dicapai dan tidak boleh dicapai. Objek boleh dicapai (hidup) jika ia dirujuk oleh objek lain yang boleh dicapai (hidup). Kebolehcapaian ditentukan daripada benang. Benang berjalan sentiasa dianggap boleh dicapai (hidup) , walaupun tiada siapa yang merujuknya."
"OK. Saya rasa saya faham."
"Bagaimanakah pengumpulan sampah sebenar berlaku—pemadaman objek yang tidak diperlukan?"
"Ia mudah. Di Jawa, ingatan dibahagikan kepada dua bahagian mengikut konvensyen, dan apabila tiba masanya untuk pengumpulan sampah, semua objek hidup (boleh dicapai) disalin ke bahagian lain memori, dan ingatan lama semuanya dikeluarkan."
"Itu pendekatan yang menarik. Tidak perlu mengira rujukan: salin semua objek yang boleh dicapai, dan yang lain adalah sampah."
"Ia sedikit lebih rumit daripada itu. Pengaturcara Java mendapati bahawa objek biasanya dibahagikan kepada dua kategori: jangka hayat (yang wujud sepanjang masa program dijalankan) dan jangka pendek (yang diperlukan dalam kaedah dan untuk melaksanakan «local »operasi)."
"Adalah lebih cekap untuk memisahkan objek yang berumur panjang daripada objek yang berumur pendek. Untuk melakukan ini, adalah perlu untuk menghasilkan satu cara untuk menentukan jangka hayat objek itu."
"Jadi, mereka membahagikan semua ingatan kepada «generasi». Terdapat objek generasi pertama, objek generasi kedua, dsb. Setiap kali memori dikosongkan, pembilang generasi ditambah sebanyak 1. Jika objek tertentu wujud dalam berbilang generasi, maka ia direkodkan sebagai berumur panjang."
"Hari ini, pemungut sampah ialah bahagian Java yang sangat kompleks dan cekap. Banyak bahagiannya berfungsi secara heuristik—berdasarkan algoritma yang membuat tekaan. Akibatnya, ia sering «tidak mendengar» pengguna."
"Maksudnya?"
"Java mempunyai objek pengumpul sampah ( GC ) yang boleh dipanggil menggunakan kaedah System.gc ()."
"Anda juga boleh menggunakan System.runFinalization() untuk memaksa panggilan ke kaedah memuktamadkan objek yang akan dipadamkan. Tetapi hakikatnya, menurut dokumentasi Java, ini tidak menjamin bahawa pengumpulan sampah akan dimulakan, mahupun penyelesaian( ) kaedah akan dipanggil. Pengumpul sampah memutuskan bila untuk memanggilnya dan tentang apa. "
"Wah! Senang tahu."
"Tetapi ada lagi. Seperti yang anda tahu, di Jawa, sesetengah objek merujuk kepada yang lain. Rangkaian rujukan ini digunakan untuk menentukan sama ada objek perlu dipadamkan."
"Dan, lihat. Java mempunyai rujukan khas yang membolehkan anda mempengaruhi proses ini. Terdapat kelas pembalut khas untuk mereka. Ini adalah:"
" SoftReference ialah rujukan lembut."
" WeakReference ialah rujukan yang lemah."
" PhantomReference ialah rujukan hantu."
"Eh... Ini mengingatkan saya tentang kelas dalam, kelas bersarang, kelas tanpa nama bersarang dan kelas tempatan. Namanya berbeza, tetapi tidak jelas sama sekali untuk tujuan mereka."
"Katakan, Amigo, anda telah menjadi seorang pengaturcara. Sekarang anda marah kerana nama kelas, mengatakan «mereka tidak cukup bermaklumat, dan mustahil dengan satu nama(!) untuk menentukan apa yang kelas ini lakukan, bagaimana, dan mengapa"."
"Wah. Saya tak perasan pun. Tapi nampak sangat."
"OK. Cukup kata. Biar saya ceritakan tentang SoftReferences."
"Rujukan ini direka khusus untuk caching, walaupun ia boleh digunakan untuk tujuan lain-semuanya mengikut budi bicara pengaturcara."
"Berikut ialah contoh rujukan sedemikian:"
// Create a Cat object
Cat cat = new Cat();
// Create a soft reference to a Cat object
SoftReference<Cat> catRef = new SoftReference<Cat>(cat);
// Now only the catRef soft reference points at the object
cat = null;
// Now the ordinary cat variable also references the object
cat = catRef.get();
// Clear the soft reference
catRef.clear();
"Jika satu-satunya rujukan kepada objek adalah lembut, maka ia terus hidup dan dipanggil 'boleh dicapai dengan lembut'."
"Tetapi! Objek yang dirujuk hanya oleh rujukan lembut boleh dipadamkan oleh pengumpul sampah jika program tidak mempunyai memori yang mencukupi. Jika tiba-tiba program tidak mempunyai memori yang mencukupi, sebelum membuang OutOfMemoryException , pengumpul sampah akan memadam semua objek dirujuk oleh rujukan lembut dan akan cuba lagi untuk memperuntukkan memori kepada program."
"Andaikan program pelanggan kerap meminta pelbagai data daripada program pelayan. Program pelayan boleh menggunakan SoftReference untuk menyimpan sebahagian daripadanya. Jika objek yang disimpan daripada kematian oleh rujukan lembut mengambil sebahagian besar memori, maka pengumpul sampah hanya memadamkannya. semua. Cantik!"
"Ya. Saya sendiri sukakannya."
"Nah, satu tambahan kecil: Kelas SoftReference mempunyai dua kaedah. Kaedah get() mengembalikan objek yang dirujuk oleh SoftReference . Jika objek telah dipadamkan oleh pengumpul sampah, kaedah get () tiba-tiba akan mula mengembalikan null."
"Pengguna juga boleh mengosongkan SoftReference secara eksplisit dengan memanggil kaedah clear(). Dalam kes ini, pautan lemah di dalam objek SoftReference akan dimusnahkan."
"Itu sahaja buat masa ini."
"Terima kasih atas cerita yang menarik, Ellie. Ia benar-benar sangat menarik."
GO TO FULL VERSION