AFAIK, spesifikasi JVM (ditulis dalam bahasa Inggris) tidak menyebutkan kapan objek (atau nilai) yang tepat harus dihapus, dan membiarkannya untuk implementasi (demikian juga untuk R5RS ). Entah bagaimana itu membutuhkan atau menyarankan seorang pemulung, tetapi menyerahkan detailnya pada implementasinya. Dan juga untuk spesifikasi Java.
Ingat bahwa bahasa pemrograman adalah spesifikasi ( sintaks , semantik , dll ...), bukan implementasi perangkat lunak. Bahasa seperti Java (atau JVM) memiliki banyak implementasi. Spesifikasinya diterbitkan , dapat diunduh (sehingga Anda dapat mempelajarinya) dan ditulis dalam bahasa Inggris. §2.5.3 Tumpukan spesifikasi JVM menyebutkan seorang pemulung:
Penyimpanan tumpukan untuk benda-benda direklamasi oleh sistem manajemen penyimpanan otomatis (dikenal sebagai pengumpul sampah); objek tidak pernah secara eksplisit dialokasikan. Java Virtual Machine tidak mengasumsikan tipe tertentu dari sistem manajemen penyimpanan otomatis
(Penekanan adalah milik saya; Finalisasi BTW disebutkan dalam §12.6 dari spesifikasi Java, dan model memori ada di §17.4 dari spesifikasi Java)
Jadi (di Jawa) Anda seharusnya tidak peduli ketika suatu objek dihapus , dan Anda bisa mengkodekan as-jika itu tidak terjadi (dengan alasan dalam abstraksi di mana Anda mengabaikannya). Tentu saja Anda perlu memperhatikan konsumsi memori dan set objek hidup, yang merupakan pertanyaan yang berbeda . Dalam beberapa kasus sederhana (pikirkan program "hello world") Anda dapat membuktikan - atau meyakinkan diri sendiri - bahwa memori yang dialokasikan agak kecil (misalnya kurang dari satu gigabyte), dan kemudian Anda tidak peduli sama sekali tentang penghapusan objek individual . Dalam lebih banyak kasus, Anda dapat meyakinkan diri Anda bahwa benda itu hidup(atau yang dapat dijangkau, yang merupakan superset - lebih mudah untuk alasan - hidup) tidak pernah melebihi batas yang wajar (dan kemudian Anda benar-benar mengandalkan GC, tetapi Anda tidak peduli bagaimana dan kapan pengumpulan sampah terjadi). Baca tentang kompleksitas ruang .
Saya kira pada beberapa implementasi JVM yang menjalankan program Java berumur pendek seperti hello world one, pengumpul sampah tidak dipicu sama sekali dan tidak ada penghapusan terjadi. AFAIU, perilaku seperti itu sesuai dengan banyak spesifikasi Java.
Sebagian besar implementasi JVM menggunakan teknik penyalinan generasional (setidaknya untuk sebagian besar objek Java, yang tidak menggunakan finalisasi atau referensi lemah ; dan finalisasi tidak dijamin akan terjadi dalam waktu singkat dan dapat ditunda, jadi ini hanya fitur yang bermanfaat bahwa kode Anda tidak boleh sangat bergantung pada) di mana gagasan menghapus objek individual tidak masuk akal (karena blok besar memori - yang berisi zona memori untuk banyak objek -, mungkin beberapa megabyte sekaligus, dapat dilepaskan sekaligus).
Jika spesifikasi JVM mengharuskan setiap objek untuk dihapus sesegera mungkin (atau hanya menempatkan lebih banyak kendala pada penghapusan objek), teknik GC generasi yang efisien akan dilarang, dan perancang Java dan JVM telah bijaksana dalam menghindarinya.
BTW, bisa jadi mungkin JVM naif yang tidak pernah menghapus objek dan tidak melepaskan memori mungkin sesuai dengan spesifikasi (surat, bukan semangat) dan tentu saja dapat menjalankan hal halo dunia dalam praktiknya (perhatikan bahwa sebagian besar program Java yang kecil dan berumur pendek mungkin tidak mengalokasikan lebih dari beberapa gigabytes memori). Tentu saja seperti JVM tidak layak disebut dan hanya hal mainan (seperti yang ini pelaksanaan malloc
untuk C). Lihat Epsilon NoOp GC untuk informasi lebih lanjut. JVM kehidupan nyata adalah perangkat lunak yang sangat kompleks dan memadukan beberapa teknik pengumpulan sampah.
Juga, Java tidak sama dengan JVM, dan Anda memiliki implementasi Java berjalan tanpa JVM (misalnya depan-of-waktu compiler Java, runtime Android ). Dalam beberapa kasus (sebagian besar yang akademis), Anda mungkin membayangkan (disebut teknik "pengumpulan sampah waktu") bahwa program Java tidak mengalokasikan atau menghapus pada saat runtime (misalnya karena kompilator pengoptimal telah cukup pintar untuk hanya menggunakan tumpukan panggilan dan variabel otomatis ).
Mengapa objek Java tidak dihapus segera setelah mereka tidak lagi direferensikan?
Karena spesifikasi Java dan JVM tidak memerlukan itu.
Baca buku pegangan GC untuk informasi lebih lanjut (dan spesifikasi JVM ). Perhatikan bahwa menjadi hidup (atau berguna untuk perhitungan di masa depan) untuk suatu objek adalah properti seluruh program (non-modular).
Objective-C mendukung pendekatan penghitungan referensi untuk manajemen memori . Dan itu juga memiliki jebakan (misalnya programmer Objective-C harus peduli tentang referensi melingkar dengan menjelaskan referensi yang lemah, tetapi JVM menangani referensi melingkar dengan baik dalam praktek tanpa memerlukan perhatian dari programmer Java).
Tidak Ada Peluru Perak dalam pemrograman dan desain bahasa pemrograman (waspadai Masalah Pemutusan ; menjadi objek hidup yang bermanfaat tidak dapat diputuskan secara umum).
Anda mungkin juga membaca SICP , Memprogram Bahasa Pragmatik , Buku Naga , Cincang Dalam Potongan - potongan Kecil dan Sistem Operasi: Tiga Potong Mudah . Mereka bukan tentang Java, tetapi mereka akan membuka pikiran Anda dan harus membantu untuk memahami apa yang harus dilakukan JVM dan bagaimana cara kerjanya secara praktis (dengan bagian lain) di komputer Anda. Anda juga dapat menghabiskan waktu berbulan-bulan (atau beberapa tahun) untuk mempelajari kode sumber kompleks dari implementasi JVM open source yang ada (seperti OpenJDK , yang memiliki beberapa juta baris kode sumber).