Saya telah membaca artikel ini tentang topik tersebut, tetapi saya tidak begitu memahaminya. Tolong beri saya beberapa saran bersama dengan contoh ketika menjelaskan konsep.
Saya telah membaca artikel ini tentang topik tersebut, tetapi saya tidak begitu memahaminya. Tolong beri saya beberapa saran bersama dengan contoh ketika menjelaskan konsep.
Jawaban:
Java menyediakan dua jenis / kelas Objek Referensi : kuat dan lemah . Obyek Referensi yang Lemah dapat dibagi lagi menjadi lunak dan hantu .
Mari kita selangkah demi selangkah.
Obyek Referensi Kuat
StringBuilder builder = new StringBuilder();
Ini adalah tipe / kelas default dari Object Reference, jika tidak ditentukan secara berbeda: builder
adalah Object Reference yang kuat. Referensi semacam ini membuat objek yang dirujuk tidak memenuhi syarat untuk GC. Yaitu, setiap kali sebuah objek direferensikan oleh rantai Objek Referensi yang kuat , itu tidak bisa menjadi sampah yang dikumpulkan.
Obyek Referensi Lemah
WeakReference<StringBuilder> weakBuilder = new WeakReference<StringBuilder>(builder);
Objek Referensi Lemah bukan tipe / kelas default dari Objek Referensi dan untuk digunakan mereka harus secara eksplisit ditentukan seperti pada contoh di atas. Referensi semacam ini membuat objek referensi memenuhi syarat untuk GC. Artinya, jika satu-satunya referensi yang dapat dijangkau untuk StringBuilder
objek dalam memori, sebenarnya, adalah referensi yang lemah, maka GC diizinkan untuk mengumpulkan sampah StringBuilder
objek. Ketika suatu objek dalam memori hanya dapat dijangkau oleh Objek Referensi Lemah, objek tersebut secara otomatis memenuhi syarat untuk GC.
Tingkat Kelemahan
Dua tingkat kelemahan yang berbeda dapat dimasukkan: lunak dan hantu .
Sebuah lembut Obyek Referensi pada dasarnya adalah Object Reference lemah yang tetap dalam memori sedikit lebih: biasanya, menolak siklus GC sampai tidak ada memori yang tersedia dan ada risiko OutOfMemoryError
(dalam hal ini, dapat dihapus).
Di sisi lain, Obyek Referensi hantu hanya berguna untuk mengetahui dengan tepat kapan suatu objek telah dihapus secara efektif dari memori: biasanya mereka digunakan untuk memperbaiki perilaku penyelesaian / kebangkitan yang aneh , karena mereka sebenarnya tidak mengembalikan objek itu sendiri tetapi hanya membantu melacak keberadaan ingatan mereka .
Objek Referensi Lemah sangat ideal untuk mengimplementasikan modul cache. Bahkan, semacam penggusuran otomatis dapat diimplementasikan dengan memungkinkan GC untuk membersihkan area memori setiap kali objek / nilai tidak lagi dapat dijangkau oleh rantai referensi yang kuat. Contohnya adalah WeakHashMap yang mempertahankan kunci lemah.
Referensi yang lemah:
Referensi yang lemah, sederhananya, adalah referensi yang tidak cukup kuat untuk memaksa objek untuk tetap berada dalam memori. Referensi yang lemah memungkinkan Anda memanfaatkan kemampuan pengumpul sampah untuk menentukan jangkauan Anda, sehingga Anda tidak harus melakukannya sendiri.
Referensi Lembut:
Referensi lunak persis seperti referensi lemah, kecuali bahwa ia kurang bersemangat untuk membuang objek yang dirujuk. Objek yang hanya dapat dijangkau dengan lemah (referensi terkuat untuk itu adalah Referensi Lemah) akan dibuang pada siklus pengumpulan sampah berikutnya, tetapi objek yang dapat dijangkau dengan lembut umumnya akan bertahan untuk sementara waktu.
Referensi Phantom:
Referensi hantu sangat berbeda dari SoftReference atau WeakReference. Cengkeramannya pada objek sangat lemah sehingga Anda bahkan tidak dapat mengambil objek - metode get () selalu mengembalikan null. Satu-satunya penggunaan untuk referensi semacam itu adalah melacak ketika itu akan enqueued menjadi ReferenceQueue, karena pada titik itu Anda tahu objek yang ditunjuknya sudah mati.
Teks ini diekstraksi dari: https://weblogs.java.net/blog/2006/05/04/understanding-weak-references
Perbedaan sederhana antara SoftReference
dan WeakReference
disediakan oleh Pengembang Android .
Perbedaan antara a SoftReference
dan a WeakReference
adalah titik waktu di mana keputusan dibuat untuk menghapus dan membuat rujukan referensi:
A SoftReference
harus dibersihkan dan enqueued selambat mungkin, yaitu, jika VM dalam bahaya kehabisan memori.
A WeakReference
dapat dihapus dan enqueued segera setelah diketahui memiliki referensi lemah.
Tiga istilah yang telah Anda gunakan sebagian besar terkait dengan kelayakan Objek untuk mengumpulkan sampah.
Referensi Lemah :: Ini adalah referensi yang tidak cukup kuat untuk memaksa objek tetap berada di memori. Ini adalah pengumpul sampah yang ingin mengumpulkan benda itu untuk pengumpulan sampah. Anda tidak dapat memaksa GC untuk tidak mengambilnya .
Referensi Lembut :: Ini kurang lebih sama seperti referensi lemah. Tetapi Anda dapat mengatakan bahwa itu memegang objek sedikit lebih kuat daripada referensi lemah dari pengumpulan sampah.
Jika pengumpul sampah mengumpulkan referensi lemah dalam siklus kehidupan pertama itu sendiri, ia akan mengumpulkan referensi lunak dalam siklus pengumpulan sampah berikutnya.
Referensi Kuat :: Ini bertolak belakang dengan dua jenis referensi di atas. Mereka kurang suka mengumpulkan sampah (Kebanyakan mereka tidak pernah dikumpulkan.)
Anda dapat merujuk ke tautan berikut untuk info lebih lanjut:
http://docs.oracle.com/javase/1.4.2/docs/api/java/lang/ref/Reference.html
Artikel ini bisa sangat membantu untuk memahami referensi yang kuat, lembut, lemah dan phantom.
Untuk memberi Anda ringkasan,
Jika Anda memiliki referensi yang kuat ke suatu objek, maka objek tersebut tidak pernah dapat dikumpulkan / direklamasi oleh GC (Pengumpul Sampah).
Jika Anda hanya memiliki referensi lemah ke objek (tanpa referensi kuat), maka objek tersebut akan direklamasi oleh GC dalam siklus GC berikutnya.
Jika Anda hanya memiliki referensi lunak ke suatu objek (tanpa referensi kuat), maka objek tersebut akan direklamasi oleh GC hanya ketika JVM kehabisan memori.
Kami membuat referensi hantu ke objek untuk melacak ketika objek enqueued ke dalam ReferenceQueue
. Setelah Anda tahu bahwa Anda dapat melakukan finalisasi berbutir halus. (Ini akan menyelamatkan Anda dari secara tidak sengaja menghidupkan kembali objek karena referensi hantu tidak memberi Anda referensi). Saya sarankan Anda membaca artikel ini untuk mendapatkan detail mendalam tentang ini.
Jadi Anda dapat mengatakan bahwa, referensi yang kuat memiliki kekuatan tertinggi (tidak pernah dapat dikumpulkan oleh GC)
Referensi lunak lebih kuat daripada referensi yang lemah (karena mereka dapat keluar dari siklus GC sampai JVM kehabisan memori)
Referensi yang lemah bahkan kurang kuat daripada referensi lunak (karena mereka tidak dapat lepas dari siklus GC dan akan direklamasi jika objek tidak memiliki referensi kuat lainnya).
Analogi Restoran
Sekarang jika Anda adalah pelanggan yang kuat (analog dengan referensi kuat), maka bahkan jika pelanggan baru datang di restoran atau apa yang pernah terjadi, Anda tidak akan pernah meninggalkan meja Anda (area memori di tumpukan). Pelayan tidak berhak untuk memberitahu Anda (atau bahkan meminta Anda) untuk meninggalkan restoran.
Jika Anda adalah pelanggan lunak (analog dengan referensi lembut), maka jika pelanggan baru datang di restoran, pelayan tidak akan meminta Anda untuk meninggalkan meja kecuali tidak ada meja kosong yang tersisa untuk mengakomodasi pelanggan baru. (Dengan kata lain pelayan akan meminta Anda untuk meninggalkan meja hanya jika pelanggan baru masuk dan tidak ada meja lain yang tersisa untuk pelanggan baru ini)
Jika Anda adalah pelanggan yang lemah (analog dengan referensi lemah), maka pelayan, atas kehendaknya, dapat (kapan saja) meminta Anda untuk meninggalkan restoran: P
4 derajat referensi - Strong, Weak, Soft, Phantom
Kuat - adalah semacam referensi, yang membuat objek yang direferensikan tidak memenuhi syarat untuk GC. kelas pembangun. misalnya - StringBuilder
Lemah - adalah referensi yang memenuhi syarat untuk GC.
Soft - adalah jenis referensi yang objeknya memenuhi syarat untuk GC sampai memori tersedia. Terbaik untuk cache gambar. Ini akan menahan mereka sampai memori tersedia.
Phantom - adalah sejenis referensi yang objeknya secara langsung memenuhi syarat untuk GC. Digunakan hanya untuk mengetahui kapan suatu objek dihapus dari memori.
menggunakan:
Memungkinkan Anda mengidentifikasi kapan suatu objek dikeluarkan dengan benar dari memori.
ketika
finalize()
metode kelebihan beban, maka GC mungkin tidak terjadi secara tepat waktu untuk objek yang memenuhi syarat GC dari dua kelas. Jadi referensi hantu membuat mereka memenuhi syarat untuk GC sebelumnyafinalize()
, itulah sebabnya Anda bisa mendapatkan OutOfMemoryErrors bahkan ketika sebagian besar tumpukan adalah sampah.
Referensi yang lemah ideal untuk mengimplementasikan modul cache.
Ini adalah referensi objek reguler Anda yang kami kode setiap hari:
Employee emp = new Employee();
Variabel "emp" memegang referensi kuat ke objek Karyawan dan objek yang dapat dijangkau melalui rantai referensi kuat apa pun tidak memenuhi syarat untuk pengumpulan sampah. Biasanya, ini yang Anda inginkan tetapi tidak selalu. Sekarang anggaplah kita mengambil banyak karyawan dari database dalam koleksi atau peta, dan kita perlu melakukan banyak pemrosesan pada mereka secara teratur, Jadi untuk menjaga kinerja, kita akan menyimpannya dalam cache.
Sejauh ini bagus tetapi sekarang kami membutuhkan data yang berbeda dan kami tidak membutuhkan objek Karyawan tersebut dan ini tidak dirujuk dari mana pun kecuali cache. Yang menyebabkan kebocoran memori karena benda-benda ini tidak digunakan tetapi masih belum memenuhi syarat untuk pengumpulan sampah dan kami tidak dapat menghapus objek-objek dari cache karena kami tidak memiliki referensi untuk itu? Jadi di sini kita perlu mengosongkan seluruh cache secara manual yang membosankan atau kita bisa menggunakan referensi jenis lain misalnya Referensi Lemah.
Referensi yang lemah tidak menyematkan objek ke memori dan akan GC di siklus GC berikutnya jika tidak dirujuk dari referensi lain. Kita bisa menggunakan kelas WeakReference yang disediakan oleh Java untuk membuat jenis cache di atas, yang tidak akan menyimpan objek yang tidak dirujuk dari tempat lain.
WeakReference<Cache> cache = new WeakReference<Cache>(data);
Untuk mengakses data, Anda perlu memanggil cache.get (). Panggilan untuk mendapatkan ini dapat mengembalikan nol jika referensi lemah adalah sampah yang dikumpulkan: Anda harus memeriksa nilai yang dikembalikan untuk menghindari NPE. Java menyediakan koleksi yang menggunakan referensi lemah misalnya, kelas WeakHashMap menyimpan kunci (bukan nilai) sebagai referensi lemah. Jika kuncinya adalah GC, maka nilai tersebut akan secara otomatis dihapus dari peta juga.
Karena referensi yang lemah adalah objek juga kita perlu cara untuk membersihkannya (mereka tidak lagi berguna ketika objek yang mereka rujuk telah GC'd). Jika Anda meneruskan ReferenceQueue ke dalam konstruktor untuk referensi yang lemah maka pemulung akan menambahkan referensi yang lemah ke ReferenceQueue sebelum mereka selesai atau GC. Anda dapat secara berkala memproses antrian ini dan menangani referensi mati.
SoftReference seperti WeakReference tetapi kecil kemungkinannya sampah yang dikumpulkan. Referensi lunak dihapus atas kebijakan pengumpul sampah dalam menanggapi permintaan memori. Mesin virtual menjamin bahwa semua referensi lunak untuk objek yang dapat dijangkau dengan lembut akan telah dihapus sebelum pernah membuang OutOfMemoryError.
Referensi Phantom adalah yang terlemah dari semua jenis referensi, memanggil get on mereka akan selalu mengembalikan nol. Objek direferensikan phantomly setelah selesai, tetapi sebelum memori yang dialokasikan telah direklamasi, Berbeda dengan referensi lemah yang enqueued sebelum mereka selesai atau GC'd referensi Phantom jarang digunakan.
Jadi, bagaimana manfaatnya? Saat Anda membuat referensi hantu Anda harus selalu memberikan ReferensiQueue. Ini menunjukkan bahwa Anda dapat menggunakan referensi hantu untuk melihat kapan objek Anda GC.
Hei, jadi jika referensi lemah enqueued ketika mereka dianggap selesai tetapi belum GC kita bisa membuat referensi kuat baru ke objek di blok finalizer dan mencegah objek menjadi GC. Yap, Anda bisa tetapi Anda mungkin tidak seharusnya melakukan ini. Untuk memeriksa kasus ini, siklus GC akan terjadi setidaknya dua kali untuk setiap objek kecuali objek itu hanya dapat dijangkau oleh referensi hantu. Inilah sebabnya mengapa Anda dapat kehabisan tumpukan bahkan ketika memori Anda mengandung banyak sampah. Referensi hantu dapat mencegah hal ini.
Anda dapat membaca lebih lanjut di artikel saya Jenis Referensi di Jawa (Strong, Soft, Weak, Phantom) .