"Hai! Aku memutuskan untuk memberimu pelajaran kecil lagi tentang pengumpulan sampah."

Seperti yang sudah Anda ketahui, mesin Java itu sendiri memantau ketika suatu objek menjadi tidak diperlukan, dan menghapusnya.

"Ya. Kamu dan Rishi memberitahuku tentang itu sebelumnya. Aku tidak ingat detailnya."

"Oke. Kalau begitu mari kita bahas lagi."

Pengumpulan sampah - 1

"Segera setelah objek dibuat, JVM mengalokasikan memori untuk itu. Minat objek dipantau menggunakan variabel referensi.  Objek dapat dihapus selama pengumpulan sampah, yaitu prosedur pelepasan memori jika tidak ada variabel yang mereferensikan objek. "

"Ceritakan sedikit tentang pengumpul sampah—apa itu dan bagaimana cara kerjanya."

"Oke. Pengumpulan sampah biasanya terjadi di utas utama. Setiap 5 menit, atau lebih sering. Jika memori kosong tidak cukup, mesin Java akan menangguhkan semua utas dan menghapus objek yang tidak digunakan."

"Tapi pendekatan ini telah ditinggalkan sekarang. Pengumpul sampah generasi berikutnya bekerja di belakang layar dan di utas terpisah. Ini disebut pengumpulan sampah bersamaan."

"Begitu. Bagaimana sebenarnya keputusan untuk menghapus objek atau tidak dibuat?"

"Hanya menghitung jumlah referensi ke suatu objek tidak terlalu efektif—mungkin ada objek yang merujuk satu sama lain, tetapi tidak direferensikan oleh objek lain."

"Jadi Java mengambil pendekatan yang berbeda.  Java membagi objek menjadi dapat dijangkau dan tidak dapat dijangkau.  Sebuah objek dapat dijangkau (hidup) jika direferensikan oleh objek lain yang dapat dijangkau (hidup). Reachability ditentukan dari utas. Menjalankan utas selalu dianggap dapat dijangkau (hidup) , bahkan jika tidak ada yang mereferensikannya."

"Oke. Kurasa aku mengerti."

"Bagaimana pengumpulan sampah yang sebenarnya terjadi—penghapusan objek yang tidak perlu?"

"Sederhana saja. Di Java, memori dibagi menjadi dua bagian berdasarkan konvensi, dan ketika tiba waktunya untuk pengumpulan sampah, semua benda hidup (dapat dijangkau) disalin ke bagian lain dari memori, dan semua memori lama dilepaskan."

"Itu pendekatan yang menarik. Tidak perlu menghitung referensi: salin semua objek yang bisa dijangkau, dan yang lainnya adalah sampah."

"Ini sedikit lebih rumit dari itu. Pemrogram Java menemukan bahwa objek biasanya dibagi menjadi dua kategori: berumur panjang (yang ada selama program berjalan) dan berumur pendek (yang diperlukan dalam metode dan untuk melakukan «local " operasi)."

"Jauh lebih efisien untuk memisahkan objek berumur panjang dari yang berumur pendek. Untuk melakukan ini, perlu ditemukan cara untuk menentukan umur panjang objek."

"Jadi, mereka membagi semua memori menjadi «generasi». Ada objek generasi pertama, objek generasi kedua, dll. Setiap kali memori dihapus, penghitung generasi bertambah 1. Jika objek tertentu ada dalam beberapa generasi, maka mereka tercatat berumur panjang."

"Saat ini, pengumpul sampah adalah bagian yang sangat kompleks dan efisien dari Java. Banyak bagiannya bekerja secara heuristik—berdasarkan algoritme yang membuat tebakan. Akibatnya, sering kali «tidak mendengarkan» pengguna."

"Arti?"

"Java memiliki objek pengumpul sampah ( GC ) yang dapat dipanggil menggunakan metode System.gc ()."

"Anda juga dapat menggunakan System.runFinalization() untuk memaksa panggilan ke metode finalisasi objek untuk dihapus. Tetapi faktanya adalah, menurut dokumentasi Java, jaminan ini tidak akan memulai pengumpulan sampah, atau penyelesaian( ) metode akan dipanggil.  Pengumpul sampah memutuskan kapan memanggilnya dan apa. "

"Wah! Senang mengetahuinya."

"Tapi masih ada lagi. Seperti yang Anda ketahui, di Jawa, beberapa objek mereferensikan yang lain. Jaringan referensi ini digunakan untuk menentukan apakah suatu objek harus dihapus."

"Dan, lihat. Java memiliki referensi khusus yang memungkinkan Anda memengaruhi proses ini. Ada kelas pembungkus khusus untuk mereka. Ini dia:"

" SoftReference  adalah referensi lembut."

" WeakReference  adalah referensi yang lemah."

" PhantomReference adalah referensi hantu."

"Uh... Ini mengingatkanku pada inner class, nested class, nested anonymous class, dan local class. Namanya berbeda, tapi sama sekali tidak jelas untuk apa mereka."

"Katakan, Amigo, kamu telah menjadi seorang programmer. Sekarang kamu marah karena nama kelas, mengatakan «mereka tidak cukup informatif, dan tidak mungkin dengan satu nama(!) untuk menentukan apa yang dilakukan kelas ini, bagaimana, dan mengapa"."

"Wow. Aku bahkan tidak menyadarinya. Tapi itu sangat jelas."

"Oke. Cukup kata-kata. Izinkan saya memberi tahu Anda tentang SoftReferences."

"Referensi ini secara khusus dirancang untuk caching, meskipun dapat digunakan untuk tujuan lain—semua atas kebijaksanaan pemrogram."

"Inilah contoh referensi semacam itu:"

Contoh
// 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 referensi ke suatu objek lunak, maka itu terus hidup dan disebut 'dapat dijangkau dengan lembut'."

"Tapi!  Objek yang direferensikan hanya dengan referensi lunak dapat dihapus oleh pengumpul sampah jika program tidak memiliki cukup memori.  Jika tiba-tiba program tidak memiliki cukup memori, sebelum membuang OutOfMemoryException , pengumpul sampah akan menghapus semua objek direferensikan oleh referensi lunak dan akan mencoba lagi untuk mengalokasikan memori ke program."

"Misalkan program klien sering meminta berbagai data dari program server. Program server dapat menggunakan SoftReference untuk menyimpan sebagian darinya. Jika objek yang disimpan dari kematian oleh referensi lunak menghabiskan sebagian besar memori, maka pengumpul sampah akan menghapusnya semua. Itu indah!"

"Ya. Aku sendiri menyukainya."

"Nah, satu tambahan kecil: Kelas SoftReference memiliki dua metode. Metode get() mengembalikan objek yang direferensikan oleh SoftReference . Jika objek dihapus oleh pengumpul sampah, metode get () akan tiba-tiba mulai mengembalikan null."

"Pengguna juga dapat menghapus SoftReference secara eksplisit dengan memanggil metode clear(). Dalam hal ini, tautan lemah di dalam objek SoftReference akan dihancurkan."

"Itu saja untuk saat ini."

"Terima kasih atas ceritanya yang menarik, Ellie. Sangat menarik."