Saya menjelajahi beberapa buku lama dan menemukan salinan "Praktis Java" oleh Peter Hagger. Di bagian performance, terdapat rekomendasi untuk mengatur referensi objek null
saat tidak diperlukan lagi.
Di Java, apakah pengaturan referensi objek untuk null
meningkatkan kinerja atau efisiensi pengumpulan sampah? Jika ya, dalam kasus apa ini menjadi masalah? Kelas kontainer? Komposisi objek? Kelas batin anonim?
Saya sering melihat ini dalam kode. Apakah saran pemrograman ini sekarang sudah usang atau masih berguna?
Jawaban:
Itu sedikit tergantung pada saat Anda berpikir untuk membatalkan referensi.
Jika Anda memiliki rantai objek A-> B-> C, maka setelah A tidak dapat dijangkau, A, B, dan C semuanya akan memenuhi syarat untuk pengumpulan sampah (dengan asumsi tidak ada hal lain yang merujuk ke B atau C). Tidak perlu, dan tidak pernah ada kebutuhan, untuk secara eksplisit mengatur referensi A-> B atau B-> C ke null, misalnya.
Selain itu, sering kali masalah tidak benar-benar muncul, karena pada kenyataannya Anda berurusan dengan objek dalam koleksi. Biasanya Anda harus selalu berpikir untuk menghapus objek dari daftar, peta, dll dengan memanggil metode appropiate remove ().
Kasus di mana dulu ada beberapa saran untuk mengatur referensi ke nol secara khusus dalam lingkup panjang di mana objek intensif memori tidak lagi digunakan di tengah ruang lingkup . Sebagai contoh:
Alasannya di sini adalah karena obj masih dalam cakupan, maka tanpa penghapusan eksplisit referensi, ia tidak menjadi sampah yang dapat dikumpulkan sampai setelah metode doSomethingElse () selesai. Dan ini adalah saran yang mungkin tidak lagi berlaku pada JVM modern : ternyata kompiler JIT dapat bekerja pada titik mana referensi objek lokal tertentu tidak lagi digunakan.
sumber
Tidak, itu bukan nasihat usang. Referensi yang menggantung masih menjadi masalah, terutama jika Anda, katakanlah, mengimplementasikan wadah array yang dapat diperluas (
ArrayList
atau sejenisnya) menggunakan array yang dialokasikan sebelumnya. Elemen di luar ukuran "logis" dari daftar harus dikosongkan, atau mereka tidak akan dibebaskan.Lihat Effective Java 2nd ed, Item 6: Eliminate Obsolete Object References.
sumber
Bidang contoh, elemen larik
Jika ada referensi ke suatu objek, maka tidak bisa sampah dikumpulkan. Apalagi jika objek itu (dan seluruh grafik di belakangnya) besar, hanya ada satu referensi yang menghentikan pengumpulan sampah, dan referensi itu tidak terlalu dibutuhkan lagi, itu adalah situasi yang sangat disayangkan.
Kasus patologis adalah objek yang mempertahankan instance unnessary ke seluruh pohon DOM XML yang digunakan untuk mengkonfigurasinya, MBean yang tidak dicabut, atau referensi tunggal ke objek dari aplikasi web yang tidak diterapkan yang mencegah seluruh classloader dibongkar .
Jadi, kecuali Anda yakin bahwa objek yang menyimpan referensi itu sendiri akan tetap menjadi sampah yang dikumpulkan (atau bahkan kemudian), Anda harus membatalkan semua yang tidak lagi Anda perlukan.
Variabel yang dicakup:
Jika Anda mempertimbangkan untuk menyetel variabel lokal ke null sebelum akhir cakupannya, sehingga dapat diklaim kembali oleh pengumpul sampah dan menandainya sebagai "tidak dapat digunakan mulai sekarang", Anda harus mempertimbangkan untuk meletakkannya dalam ruang lingkup yang lebih terbatas sebagai gantinya .
menjadi
Cakupan yang panjang dan datar biasanya buruk untuk keterbacaan kode juga. Memperkenalkan metode pribadi untuk memecah masalah hanya untuk tujuan itu bukanlah hal yang tidak biasa juga.
sumber
Dalam lingkungan yang membatasi memori (misalnya ponsel) ini dapat berguna. Dengan menyetel null, objetc tidak perlu menunggu variabel keluar dari ruang lingkup untuk di-gc.
Untuk pemrograman sehari-hari, bagaimanapun, ini seharusnya tidak menjadi aturan, kecuali dalam kasus-kasus khusus seperti yang dikutip oleh Chris Jester-Young.
sumber
Pertama, Ini tidak berarti apa pun yang Anda tetapkan sebagai objek
null
. Saya jelaskan di bawah ini:Pada segmen kode di atas kita membuat nama variabel referensi objek
list1
dariArrayList
objek yang disimpan di memori. Jadilist1
mengacu pada objek itu dan itu tidak lebih dari sebuah variabel. Dan di baris kedua kode kita menyalin referensilist1
kelist2
. Jadi sekarang kembali ke pertanyaan Anda jika saya melakukannya:itu berarti
list1
tidak lagi mengacu pada objek apa pun yang disimpan dalam memori sehinggalist2
juga tidak memiliki referensi apa pun . Jadi jika Anda memeriksa ukuranlist2
:Jadi di sini konsep pengumpul sampah muncul yang mengatakan «Anda tidak perlu khawatir tentang membebaskan memori yang dipegang oleh objek, saya akan melakukannya ketika saya menemukan bahwa itu tidak lagi digunakan dalam program dan JVM akan mengatur saya.»
Saya harap konsepnya jelas.
sumber
Salah satu alasan untuk melakukannya adalah untuk menghilangkan referensi objek usang. Anda dapat membaca teksnya di sini.
sumber