Ketika datang ke Garbage Collection (GC), banyak orang secara alami akan mengaitkannya dengan Java. Di Java, programmer tidak perlu peduli dengan alokasi memori dinamis dan pengumpulan sampah, semua ini diserahkan kepada JVM untuk ditangani.
Seperti namanya, pengumpulan sampah adalah untuk membebaskan ruang yang ditempati oleh sampah. Jadi di Java, benda apa yang akan dianggap "sampah"? Jadi ketika beberapa objek bertekad untuk menjadi sampah, strategi apa yang harus digunakan untuk mendaur ulang (ruang bebas)? Apa saja pengumpul sampah khas di mesin virtual komersial saat ini? Mari kita bahas masalah ini satu per satu. Berikut adalah garis besar direktori dari artikel ini:
Bagaimana cara menentukan apakah suatu objek adalah "sampah"?
Algoritma Pengumpulan Sampah Khas
1. Bagaimana menentukan apakah suatu objek adalah "sampah"?
Di bagian ini, pertama -tama kita memahami pertanyaan paling mendasar: jika kita menentukan bahwa suatu objek adalah "sampah"? Karena tugas pengumpul sampah adalah mendaur ulang ruang yang ditempati oleh objek sampah untuk digunakan oleh objek baru, bagaimana pengumpul sampah menentukan bahwa suatu objek adalah "sampah"? Artinya, bagaimana menilai bahwa suatu objek dapat didaur ulang.
Di Java, itu dikaitkan dengan objek melalui referensi, yaitu, jika Anda ingin mengoperasikan objek, itu harus dilakukan melalui referensi. Maka jelas bahwa cara yang mudah adalah menilai apakah suatu objek dapat didaur ulang dengan penghitungan referensi. Tanpa kehilangan sifat umum, jika suatu objek tidak memiliki referensi yang terkait dengannya, itu berarti bahwa objek pada dasarnya tidak mungkin digunakan di tempat lain, dan kemudian objek menjadi objek yang dapat didaur ulang. Metode ini menjadi metode penghitungan referensi.
Metode ini ditandai dengan implementasi sederhana dan efisiensi tinggi, tetapi tidak dapat menyelesaikan masalah referensi melingkar, sehingga metode ini tidak diadopsi dalam Java (Python menggunakan metode penghitungan referensi). Lihat kode berikut:
kelas publik {public static void main (string [] args) {myObject object1 = new myobject (); MyObject Object2 = new MyObject (); Object1.Object = Object2; Object2.Object = Object1; Object1 = null; Object2 = null; }} class myobject {objek objek publik = null;}Dua kalimat terakhir yang menetapkan Object1 dan Object2 ke Null, yang berarti bahwa objek yang ditunjuk oleh Object1 dan Object2 tidak lagi dapat diakses, tetapi karena mereka saling merujuk, jumlah referensi mereka bukan 0, maka pengumpul sampah tidak akan pernah mendaur ulangnya.
Untuk mengatasi masalah ini, metode analisis aksesibilitas diadopsi di Java. Gagasan dasar dari metode ini adalah mencari melalui serangkaian objek "GC Roots" sebagai titik awal. Jika tidak ada jalur yang dapat diakses antara "GC Roots" dan sebuah objek, objek tersebut dikatakan tidak dapat dijangkau. Namun, harus dicatat bahwa objek yang dinilai tidak dapat dijangkau mungkin tidak selalu menjadi objek yang dapat didaur ulang. Objek yang dinilai sebagai tidak terjangkau harus melalui setidaknya dua proses penandaan untuk menjadi objek yang dapat didaur ulang. Jika masih belum ada kemungkinan untuk menjadi objek yang dapat didaur ulang selama dua proses penandaan ini, itu pada dasarnya akan menjadi objek yang dapat didaur ulang.
Adapun bagaimana metode analisis aksesibilitas dioperasikan, saya belum memahaminya dengan sangat jelas. Jika ada teman yang lebih jelas, beri saya saran.
Mari kita lihat contoh di bawah ini:
Objek aobj = objek baru (); objek bobj = objek baru (); objek cobj = objek baru (); aobj = bobj; aobj = cobj; cobj = null; aobj = null;
Baris mana yang dapat membuat objek dapat didaur ulang? Kode pada baris 7 akan menyebabkan objek menjadi objek yang dapat didaur ulang. Adapun mengapa dibiarkan menjadi pembaca untuk berpikir sendiri.
Mari kita lihat contoh lain:
String str = new string ("hello"); softreference <string> sr = new Softreference <string> (string baru ("java"))); wremerreference <string> wr = New WeFreference <string> (string baru ("dunia"));Manakah dari tiga kalimat berikut yang akan membuat objek string dapat didaur ulang? Kalimat 2 dan 3, dan kalimat 2 akan menentukan objek string sebagai objek yang dapat didaur ulang ketika ada memori yang tidak mencukupi, dan dalam kalimat ketiga, objek string akan ditentukan sebagai objek yang dapat didaur ulang dalam kasus apa pun.
Akhirnya, mari kita ringkas situasi umum di mana objek dinilai sebagai objek yang dapat didaur ulang yang biasanya ditemui:
1) Tampilkan nilai referensi ke null atau arahkan referensi yang telah menunjuk ke objek ke objek baru, seperti kode berikut:
Objek obj = objek baru (); obj = null; objek obj1 = objek baru (); objek obj2 = objek baru (); obj1 = obj2;
2) Referensi lokal ke objek yang ditunjukkan, seperti kode berikut:
void fun () {...... untuk (int i = 0; i <10; i ++) {objek obj = objek baru (); System.out.println (obj.getClass ()); }}Setiap kali loop dieksekusi, objek objek yang dihasilkan akan menjadi objek yang dapat didaur ulang.
3) Hanya referensi lemah yang dikaitkan dengan objek, seperti:
Lemah Lemah <string> wr = New WeFreference <string> (string baru ("dunia"));2. Algoritma Koleksi Sampah Khas
Setelah menentukan sampah mana yang dapat didaur ulang, pengumpul sampah yang perlu dilakukan adalah memulai pengumpulan sampah, tetapi satu masalah yang terlibat adalah: bagaimana cara mengumpulkan sampah secara efisien. Karena spesifikasi mesin virtual Java tidak membuat peraturan yang jelas tentang cara mengimplementasikan pengumpul sampah, mesin virtual dari masing -masing produsen dapat mengimplementasikan pengumpul sampah dengan cara yang berbeda, sehingga hanya ide -ide inti dari beberapa algoritma pengumpulan sampah umum yang dibahas di sini.
1. Mark-Sweep (Mark-Clear) Algoritma
Ini adalah algoritma pengumpulan sampah paling dasar. Alasan mengapa dikatakan sebagai yang paling mendasar adalah bahwa itu adalah yang termudah untuk diterapkan dan ide paling sederhana. Algoritma pembersihan tanda dibagi menjadi dua tahap: tahap tanda dan tahap kliring. Tugas tahap penandaan adalah untuk menandai semua objek yang perlu didaur ulang, dan tahap kliring adalah mendaur ulang ruang yang ditempati oleh benda -benda yang ditandai. Proses spesifik ditunjukkan pada gambar di bawah ini:
Dapat dengan mudah dilihat dari gambar bahwa algoritma pembersihan tanda lebih mudah diimplementasikan, tetapi ada masalah serius bahwa mudah untuk menghasilkan fragmen memori. Terlalu banyak fragmen dapat menyebabkan ketidakmampuan menemukan ruang yang cukup saat mengalokasikan ruang untuk objek besar dalam proses berikutnya, dan memicu tindakan pengumpulan sampah baru terlebih dahulu.
2. Menyalin (salin) Algoritma
Untuk memecahkan kekurangan algoritma Mark-Sweep, algoritma penyalinan diusulkan. Ini membagi memori yang tersedia menjadi dua potong dengan ukuran yang sama berdasarkan kapasitas, hanya menggunakan satu bagian sekaligus. Ketika bagian memori ini digunakan, salin objek yang masih hidup ke bagian lain, dan kemudian bersihkan ruang memori yang digunakan sekaligus, sehingga masalah fragmentasi memori tidak akan terjadi. Proses spesifik ditunjukkan pada gambar di bawah ini:
Meskipun algoritma ini mudah diimplementasikan, efisien untuk dijalankan dan tidak mudah untuk menghasilkan fragmentasi memori, mahal untuk menggunakan ruang memori karena memori yang dapat digunakan dikurangi menjadi setengah dari yang asli.
Jelas, efisiensi algoritma penyalinan ada hubungannya dengan jumlah benda yang masih ada. Jika ada banyak objek yang masih hidup, efisiensi algoritma penyalinan akan sangat berkurang.
3. Mark-Compact (Mark-Collation) Algoritma
Untuk menyelesaikan kekurangan algoritma penyalinan dan memanfaatkan sepenuhnya ruang memori, algoritma kompak tanda-markus diusulkan. Algoritme menandai sama dengan Mark-Sheep, tetapi setelah menyelesaikan tanda, itu tidak secara langsung membersihkan objek yang dapat didaur ulang, tetapi menggerakkan semua benda hidup ke satu ujung dan kemudian membersihkan memori di luar batas ujung. Proses spesifik ditunjukkan pada gambar di bawah ini:
4. Algoritma Koleksi Generasi
Algoritma Generation Collection saat ini digunakan oleh sebagian besar kolektor sampah JVM. Gagasan intinya adalah membagi memori menjadi beberapa daerah yang berbeda sesuai dengan siklus hidup kelangsungan hidup objek. Secara umum, area tumpukan dibagi menjadi generasi lama dan generasi muda. Karakteristik generasi lama adalah bahwa hanya sejumlah kecil objek yang perlu didaur ulang setiap kali sampah dikumpulkan, sedangkan karakteristik generasi baru adalah bahwa sejumlah besar objek perlu didaur ulang setiap kali sampah dikumpulkan. Kemudian algoritma pengumpulan yang paling cocok dapat diadopsi sesuai dengan karakteristik generasi yang berbeda.
Saat ini, sebagian besar pengumpul sampah mengadopsi algoritma penyalinan untuk generasi baru, karena pada generasi baru, sebagian besar objek perlu didaur ulang setiap kali pengumpulan sampah dikumpulkan, yang berarti bahwa jumlah operasi yang perlu disalin relatif kecil, tetapi dalam kenyataan, ruang generasi baru tidak dibagi sesuai dengan rasio 1: 1. Secara umum, generasi baru dibagi menjadi ruang Eden yang lebih besar dan dua ruang penyintas yang lebih kecil. Setiap kali ruang Eden dan salah satu ruang yang selamat digunakan, ketika didaur ulang, benda-benda yang masih payah di Eden dan Survivor disalin ke ruang korban lainnya, dan kemudian Eden dan ruang yang selamat yang baru saja digunakan dibersihkan.
Karena usia tua adalah bahwa hanya sejumlah kecil objek yang didaur ulang setiap saat, algoritma kompak tanda-markus umumnya digunakan.
Perhatikan bahwa ada generasi lain di luar area tumpukan, yang merupakan generasi permanen, yang digunakan untuk menyimpan kelas kelas, konstanta, deskripsi metode, dll. Daur ulang generasi permanen terutama mendaur ulang dua bagian: konstanta yang dibuang dan kelas yang tidak berguna.
3. Kolektor Sampah Khas
Algoritma pengumpulan sampah adalah dasar teoritis daur ulang memori, dan pengumpul sampah adalah implementasi spesifik dari daur ulang memori. Berikut ini adalah deskripsi beberapa kolektor sampah yang disediakan oleh mesin virtual hotspot (JDK 7). Pengguna dapat menggabungkan kolektor yang digunakan di setiap era sesuai dengan kebutuhan mereka sendiri.
1. Serial/Serial Lama
Kolektor tua serial/serial adalah kolektor paling mendasar dan tertua. Ini adalah pengumpul utas tunggal dan harus menjeda semua utas pengguna saat melakukan pengumpulan sampah. Kolektor serial adalah seorang kolektor untuk generasi baru, menggunakan algoritma penyalinan, dan kolektor lama serial adalah kolektor untuk generasi lama, menggunakan algoritma compact tanda. Keuntungannya adalah sederhana dan efisien, tetapi kerugiannya adalah bahwa hal itu akan menyebabkan jeda bagi pengguna.
2.Parnew
Parnew Collector adalah versi multi-threaded dari kolektor serial yang menggunakan beberapa utas untuk pengumpulan sampah.
3. Paralel
Parallel Scavenge Collector adalah generasi baru kolektor multithreaded (kolektor paralel). Tidak perlu menjeda utas pengguna lain selama daur ulang. Ini menggunakan algoritma penyalinan. Kolektor ini berbeda dari dua kolektor pertama. Ini terutama untuk mencapai throughput terkontrol.
4. Paralel tua
Parallel Old adalah versi lama dari kolektor pemalas paralel (kolektor paralel) menggunakan algoritma multithreading dan compact tanda.
5.CMS
Kolektor CMS (tanda saat ini) adalah seorang kolektor yang bertujuan untuk mendapatkan waktu jeda pemulihan terpendek. Ini adalah kolektor bersamaan yang menggunakan algoritma Mark-Sweep.
6.G1
Kolektor G1 adalah pencapaian paling mutakhir dalam pengembangan teknologi kolektor saat ini. Ini adalah kolektor untuk aplikasi sisi server yang dapat memanfaatkan sepenuhnya lingkungan multi-CPU dan multi-core. Oleh karena itu adalah kolektor paralel dan konkurensi, dan dapat membangun model waktu jeda yang dapat diprediksi.
Berikut adalah beberapa hal tentang alokasi memori:
Dalam arah umum, alokasi memori objek dialokasikan pada tumpukan. Objek terutama dialokasikan dalam generasi baru ruang Eden dan dari luar angkasa, dan dalam kasus yang jarang mereka akan secara langsung dialokasikan di usia tua. Jika ruang generasi baru ruang Eden dan dari ruang tidak cukup, GC akan dimulai. Jika GC dilakukan, ruang Eden dan dari luar angkasa dapat mengakomodasi objek dan ditempatkan di ruang Eden dan dari luar angkasa.
Selama proses GC, benda -benda yang masih hidup di ruang Eden dan dari luar angkasa akan dipindahkan ke ruang angkasa, dan kemudian ruang Eden dan dari luar angkasa akan dibersihkan. Jika ke ruang tidak bisa cukup untuk menyimpan objek selama pembersihan, itu akan memindahkan objek ke usia tua. Setelah GC, ruang Eden dan ke ruang digunakan. Lain kali Anda GC, objek yang masih hidup akan disalin dari luar angkasa, dan loop akan diulang. Ketika suatu objek lolos dari GC sekali di daerah yang selamat, usia objeknya akan meningkat sebesar 1. Secara default, jika objek mencapai 15 tahun, itu akan bergerak ke usia pertengahan usia tua.
Secara umum, benda -benda besar akan secara langsung dialokasikan ke usia tua. Apa yang disebut benda besar merujuk pada objek yang membutuhkan sejumlah besar ruang penyimpanan kontinu. Jenis objek besar yang paling umum adalah susunan besar, seperti:
byte [] data = byte baru [4*1024*1024]
Jenis ruang penyimpanan ini umumnya akan dialokasikan langsung pada orang tua.
Tentu saja, aturan alokasi tidak diperbaiki 100%, yang tergantung pada jenis kombinasi kolektor sampah dan parameter JVM yang relevan saat ini sedang digunakan.
Di atas adalah semua konten artikel ini. Saya berharap ini akan membantu untuk pembelajaran semua orang dan saya harap semua orang akan lebih mendukung wulin.com.