Kata pengantar
Saya melihat pertanyaan di SegmentFault: Java memiliki mekanisme GC yang lengkap, jadi apakah akan ada masalah kebocoran memori di Java, dan dapatkah saya memberikan kasus kebocoran memori. Tampilan pertanyaan ini memberikan jawaban lengkap untuk pertanyaan ini.
Pengantar mekanisme daur ulang sampah
Selama program berjalan, setiap objek dibuat, sejumlah memori tertentu dialokasikan untuk menyimpan data objek. Jika Anda terus mengalokasikan memori, maka program akan menghadapi masalah memori yang tidak mencukupi cepat atau lambat. Jadi dalam bahasa apa pun, akan ada mekanisme pemulihan memori untuk membebaskan memori objek yang kedaluwarsa untuk memastikan bahwa memori dapat digunakan kembali.
Mekanisme daur ulang memori dapat dibagi menjadi dua jenis sesuai dengan peran implementasi. Salah satunya adalah bahwa pemrogram secara manual menyadari pelepasan memori (seperti bahasa C) dan yang lainnya adalah mekanisme daur ulang memori bawaan bahasa, seperti mekanisme pengumpulan sampah Java yang akan diperkenalkan dalam artikel ini.
Mekanisme Pengumpulan Sampah Java
Dalam lingkungan runtime program, Java Virtual Machine menyediakan utas koleksi sampah tingkat sistem (GC, koleksi karbage), yang bertanggung jawab untuk mengklaim kembali memori yang ditempati oleh objek yang telah kehilangan referensi. Prasyarat untuk memahami GC adalah memahami beberapa konsep yang berkaitan dengan pengumpulan sampah. Konsep -konsep ini diperkenalkan satu per satu sebagai berikut.
Keadaan objek di area tumpukan JVM
Contoh objek Java disimpan di area tumpukan JVM. Untuk utas GC, objek -objek ini memiliki tiga status.
1. Keadaan yang dapat disentuh: Ada referensi variabel dalam program, jadi objek ini adalah keadaan yang dapat disentuh.
2. Keadaan Diaktifkan: Ketika tidak ada variabel dalam program mengacu pada objek ini, objek akan berubah dari keadaan yang dapat disentuh ke keadaan yang diaktifkan kembali. Utas CG akan bersiap untuk memanggil metode finalisasi objek ini pada waktu tertentu (metode finalisasi mewarisi atau menulis ulang objek anak). Kode dalam metode finalisasi dapat mengubah objek menjadi keadaan yang dapat disentuh, jika tidak objek akan dikonversi menjadi keadaan yang tidak tersentuh.
3. Keadaan yang tidak tersentuh: Utas GC dapat mendaur ulang memori objek ini hanya ketika objek berada dalam keadaan yang tidak tersentuh.
Untuk melepaskan objek dengan benar, GC harus memantau status berjalan dari setiap objek, termasuk aplikasi, kutipan, kutipan, penugasan, dll. GC perlu memantau, jadi GC akan tahu tidak peduli apakah suatu objek dalam keadaan apa pun di atas.
Seperti disebutkan di atas, utas GC akan menjalankan metode finalisasi objek negara yang dapat dibangkitkan pada waktu tertentu. Jadi kapan akan dieksekusi? Karena pelaksana JVM yang berbeda dapat menggunakan algoritma yang berbeda untuk mengelola GC, kapan saja, pengembang tidak dapat memprediksi waktu utas GC yang melakukan berbagai operasi (termasuk mendeteksi keadaan objek, melepaskan memori objek, dan memanggil metode finalisasi objek). Meskipun utas GC dapat diingatkan untuk melakukan operasi pengumpulan sampah sesegera mungkin melalui fungsi sistem.gc () dan runtime.gc (), ini tidak dapat menjamin bahwa utas GC akan melakukan operasi daur ulang yang sesuai segera.
Bocor memori
Kebocoran memori disebabkan oleh desain yang salah bahwa program gagal melepaskan memori yang tidak lagi digunakan, menghasilkan pemborosan sumber daya. GC akan secara otomatis membersihkan memori yang ditempati oleh objek yang telah kehilangan referensi. Namun, jika beberapa objek selalu dirujuk karena kesalahan pemrograman, kebocoran memori akan terjadi.
Misalnya, contoh berikut. Array digunakan untuk mengimplementasikan tumpukan, dengan dua operasi: Stack Entry dan Stack Exit.
Impor com.sun.javafx.collections.elementObservableListDecorator; import com.sun.swing.internal.plaf.metal.resources.metal_sv; import java.beans.exceptionlistener; Impor java.util.emptystackexception; /*.xceptionlistener; */kelas publik MyStack {Private Object [] Elements; private int increment = 10; Ukuran int pribadi = 0; publik mystack (ukuran int) {elemen = objek baru [ukuran]; } // letakkan tumpukan public public void (objek o) {kapasitas (); elemen [ukuran ++] = o; } // Letakkan tumpukan objek publik pop () {if (size == 0) Lempar baru kosongStackException (); elemen pengembalian [-ukuran]; } // Tingkatkan kapasitas stack private void kapasitas () {if (elements.length! = Size) kembali; Objek [] newArray = Objek baru [elemen.length + increment]; System.ArrayCopy (Elemen, 0, NewArray, 0, Size); } public static void main (string [] args) {mystack stack = new mystack (100); untuk (int i = 0; i <100; i ++) stack.push (integer baru (i)); untuk (int i = 0; i <100; i ++) {System.out.println (stack.pop (). ToString ()); }}}Program ini tersedia dan mendukung Operasi Entri Tumpukan dan Stack Entry Umum. Namun, ada masalah yang belum ditangani dengan baik, yaitu, ketika operasi tumpukan dilepaskan, referensi ke elemen tumpukan dalam array tidak dirilis, yang menyebabkan program tetap referensi ke objek ini (objek ini dirujuk oleh array). GC selalu percaya bahwa objek ini dapat diakses, yang berarti tidak perlu berbicara tentang melepaskan ingatannya. Ini adalah kasus khas kebocoran memori. Untuk ini, kode yang dimodifikasi adalah:
// menumpuk objek publik pop () {if (size == 0) Lempar baru kosongStackException (); Objek o = elemen [-ukuran]; elemen [ukuran] = null; kembali o; }Artikel di atas memiliki pemahaman yang mendalam tentang mekanisme pengumpulan sampah Java dan kebocoran memori. Ini semua konten yang telah saya bagikan dengan Anda. Saya harap ini dapat memberi Anda referensi dan saya harap Anda dapat mendukung wulin.com lebih lanjut.