1. Mekanisme daur ulang sampah - GC
JavaScript memiliki mekanisme pengumpulan sampah otomatis (GC: pengumpulan sampah), yang berarti bahwa lingkungan eksekusi bertanggung jawab untuk mengelola memori yang digunakan selama eksekusi kode.
Prinsip: Pengumpul sampah secara berkala (periodik) menemukan variabel yang tidak digunakan dan kemudian membebaskan ingatan mereka.
Mekanisme koleksi sampah JavaScript sangat sederhana: cari tahu variabel yang tidak lagi digunakan dan kemudian membebaskan memori yang ditempati. Namun, proses ini tidak real-time karena overheadnya relatif besar, sehingga pengumpul sampah akan mengeksekusi secara berkala pada interval waktu tetap .
Variabel yang tidak lagi digunakan adalah variabel yang mengakhiri siklus hidup. Tentu saja, mereka hanya bisa menjadi variabel lokal. Siklus hidup variabel global tidak akan berakhir sampai browser menghapus instalasi halaman. Variabel lokal hanya ada selama pelaksanaan fungsi, dan dalam proses ini, ruang yang sesuai akan dialokasikan untuk variabel lokal pada tumpukan atau tumpukan untuk menyimpan nilai -nilainya, dan kemudian variabel -variabel ini digunakan dalam fungsi hingga akhir fungsi. Namun, karena fungsi internal dalam penutupan, fungsi eksternal tidak dapat dianggap berakhir.
Mari kita jelaskan kodenya:
function fn1 () {var obj = {name: 'hanzichi', usia: 10};} function fn2 () {var obj = {name: 'hanzichi', usia: 10}; return obj;} var a = fn1 (); var b = fn2 ();Mari kita lihat bagaimana kode dieksekusi. Pertama, dua fungsi didefinisikan, disebut fn1 dan fn2. Ketika FN1 dipanggil, memasuki lingkungan FN1 akan membuka objek penyimpanan memori {nama: 'hanzichi', usia: 10}. Ketika panggilan selesai dan lingkungan FN1 keluar, blok memori akan secara otomatis dilepaskan oleh pengumpul sampah di mesin JS; Selama proses FN2 dipanggil, objek yang dikembalikan ditunjukkan oleh variabel global B, sehingga blok memori tidak akan dilepaskan.
Di sini muncul pertanyaan: variabel mana yang tidak berguna? Oleh karena itu, pengumpul sampah harus melacak variabel mana yang tidak berguna dan menandai variabel yang tidak lagi berguna untuk merebut kembali ingatannya di masa depan. Strategi untuk variabel yang tidak berguna yang digunakan untuk menandai mungkin berbeda dengan implementasi, dan biasanya ada dua cara untuk melakukan ini: tandai izin dan penghitungan referensi. Penghitungan kutipan tidak terlalu umum, kliring tanda lebih umum digunakan.
2. Clear Mark
Metode pengumpulan sampah yang paling umum digunakan dalam JS adalah penghapusan tanda. Ketika variabel memasuki lingkungan, misalnya, menyatakan variabel dalam suatu fungsi, itu menandai variabel sebagai "masukkan lingkungan". Secara logis, memori yang ditempati oleh variabel yang memasuki lingkungan tidak dapat dilepaskan, karena mereka dapat digunakan selama aliran eksekusi memasuki lingkungan yang sesuai. Dan ketika sebuah variabel meninggalkan lingkungan, itu ditandai sebagai "di luar lingkungan".
function test () {var a = 10; // ditandai, masukkan lingkungan var b = 20; // ditandai, masukkan lingkungan} test (); // Setelah eksekusi, A dan B ditandai, tinggalkan lingkungan dan didaur ulang.Ketika pengumpul sampah berjalan, itu menandai semua variabel yang disimpan dalam memori (tentu saja, metode penandaan dapat digunakan). Kemudian menghilangkan tag (penutupan) variabel di lingkungan dan variabel yang dirujuk oleh variabel di lingkungan. Variabel yang ditandai setelah ini akan dianggap sebagai variabel yang siap dihapus karena variabel di lingkungan tidak dapat lagi mengakses variabel -variabel ini. Akhirnya, pengumpul sampah melengkapi pekerjaan kliring memori, menghancurkan nilai -nilai yang ditandai itu dan merebut kembali ruang memori yang mereka tempati.
Sejauh ini, implementasi JS dari IE, Firefox, Opera, Chrome, dan Safari menggunakan strategi pengumpulan sampah-pembersih Mark-Clearing atau strategi serupa, tetapi interval waktu pengumpulan sampah berbeda satu sama lain.
3. Hitungan kutipan
Arti jumlah referensi adalah untuk melacak berapa kali setiap nilai dirujuk. Ketika suatu variabel dinyatakan dan nilai tipe referensi ditetapkan untuk variabel, jumlah referensi ke nilai ini adalah 1. Jika nilai yang sama ditetapkan ke variabel lain, jumlah referensi ke nilai meningkat sebesar 1. Secara bertentangan, jika variabel yang mengandung nilai ini tidak ada nilai, jumlahnya, no itu berarti no yang berarti bahwa no itu berarti bahwa no itu berarti bahwa no itu berarti bahwa no itu berarti bahwa no itu berarti bahwa no itu berarti bahwa no itu berarti bahwa no itu berarti no itu berarti no itu berarti no itu berarti bahwa no berarti bahwa no.se no the the no the the no the the no way No the The No the The No the The No Playse Way The No Berada, No Measing No No Measing No No Measing No No Mease No No Mease Are Plerence, No No No No No No No No No No Referensi, No No No Reference No Reference No Reference Nilai. Itu menempati dapat direklamasi. Dengan cara ini, ketika pengumpul sampah berjalan lagi di lain waktu, itu membebaskan memori yang menghargai 0 referensi.
function test () {var a = {}; // Jumlah referensi A adalah 0 var b = a; // Jumlah referensi A adalah 1 var c = a; // Jumlah referensi A adalah 1, dan jumlah referensi A adalah 1, dan jumlah referensi A adalah 1, dan jumlah referensi A adalah 2 var b = {}; // Jumlah referensi A adalah 1, dan jumlah referensi A adalah 1}Netscape Navigator3 adalah browser pertama yang menggunakan strategi penghitungan referensi, tetapi segera mengalami masalah serius: referensi melingkar. Referensi melingkar mengacu pada objek A yang berisi pointer ke objek B, dan objek B juga berisi referensi ke objek A.
fungsi fn () {var a = {}; var b = {}; A.pro = b; b.pro = a;} fn ();Waktu referensi A dan B di atas adalah 2. Setelah fn () dieksekusi, kedua objek telah meninggalkan lingkungan. Tidak ada masalah dalam mode kliring tanda. Namun, di bawah strategi penghitungan referensi, karena waktu referensi A dan B bukan 0, memori tidak akan dikumpulkan oleh pengumpul sampah. Jika fungsi FN disebut dalam jumlah besar, kebocoran memori akan terjadi. Pada IE7 dan IE8, memori naik tajam.
Kita tahu bahwa beberapa objek di IE bukan objek JS asli. Misalnya, objek dalam DOM dan BOM diimplementasikan dalam bentuk objek COM menggunakan C ++, dan mekanisme pengumpulan sampah dari objek COM mengadopsi strategi penghitungan referensi. Oleh karena itu, bahkan jika mesin IE JS mengadopsi strategi kliring tag, objek COM yang diakses oleh JS masih didasarkan pada strategi penghitungan referensi. Dengan kata lain, selama objek COM terlibat dalam IE, akan ada masalah referensi melingkar.
var element = document.geteLementById ("some_element"); var myobject = objek baru (); myobject.e = element; element.o = myobject;Contoh ini membuat referensi melingkar antara elemen DOM dan objek JS asli. Di antara mereka, variabel myObject memiliki atribut bernama elemen yang menunjuk pada objek elemen; dan elemen variabel juga memiliki atribut bernama O Back untuk merujuk ke MyObject. Karena referensi melingkar ini, bahkan jika DOM dalam contoh dihapus dari halaman, itu tidak akan pernah didaur ulang.
Melihat contoh di atas, beberapa siswa berpikir itu terlalu lemah. Siapa yang akan melakukan hal yang membosankan? Faktanya, apakah kita melakukannya?
window.onload = function OutFunction () {var obj = document.geteLementById ("elemen"); obj.onClick = function innerFunction () {};};Kode ini tampaknya baik -baik saja, tetapi OBJ mengacu pada Document.getElementById ("Elemen"), dan metode OnClick dari Document.getElementById ("Elemen") akan merujuk pada variabel Jerman di lingkungan eksternal, yang secara alami juga termasuk OBJ. Bukankah itu sangat tersembunyi?
Larutan
Cara termudah adalah dengan tidak merujuk secara manual loop, misalnya, fungsi baru saja dapat melakukan ini.
myObject.element = null; element.o = null;
window.onload = function OutFunction () {var obj = document.geteLementById ("elemen"); obj.onClick = function innerFunction () {}; obj = null;};Mengatur variabel ke null berarti memotong koneksi antara variabel dan nilai yang dirujuk sebelumnya. Ketika pengumpul sampah berjalan di waktu berikutnya, nilai -nilai ini dihapus dan memori yang mereka tempati didaur ulang.
Perlu dicatat bahwa IE9+ tidak memiliki referensi melingkar untuk menyebabkan kebocoran memori DOM. Mungkin Microsoft telah mengoptimalkannya, atau metode daur ulang DOM telah berubah.
4. Manajemen Memori
1. Kapan pengumpulan sampah akan dipicu?
Kolektor sampah berjalan secara berkala. Jika memori yang dialokasikan sangat besar, pekerjaan daur ulang akan sangat sulit. Menentukan interval waktu pengumpulan sampah menjadi pertanyaan yang layak dipikirkan. Koleksi sampah IE6 berjalan sesuai dengan alokasi memori. Ketika ada 256 variabel, 4096 objek, dan 64K string di lingkungan, pengumpul sampah akan dipicu. Itu terlihat sangat ilmiah dan tidak perlu dipanggil sesekali untuk sementara waktu. Terkadang tidak perlu. Bukankah baik untuk memanggil permintaan seperti ini? Tetapi jika ada begitu banyak variabel di lingkungan, dan skripnya sangat kompleks dan normal sekarang, maka hasilnya adalah bahwa pengumpul sampah selalu berfungsi, sehingga browser tidak dapat bermain.
Microsoft telah membuat penyesuaian di IE7. Kondisi pemicu tidak lagi diperbaiki, tetapi dimodifikasi secara dinamis. Nilai awalnya sama dengan IE6. Jika alokasi memori yang dikumpulkan oleh pengumpul sampah kurang dari 15% dari memori yang ditempati oleh program, itu berarti bahwa sebagian besar memori tidak dapat didaur ulang. Kondisi pemicu pengumpulan sampah yang ditetapkan terlalu sensitif. Pada saat ini, gandakan kondisi jalanan. Jika memori yang dikumpulkan lebih tinggi dari 85%, itu berarti bahwa sebagian besar memori harus dibersihkan sejak lama. Pada saat ini, kondisi pemicu diatur kembali. Ini membuat pekerjaan daur ulang sampah lebih banyak fungsi
2. Solusi GC yang masuk akal
1) Solusi GC dasar dari mesin JavaScript adalah (GC sederhana): tanda dan sapuan, yaitu:
2) Cacat GC
Seperti bahasa lain, kebijakan GC JavaScript tidak dapat menghindari satu masalah: ketika GC, berhenti menanggapi operasi lain, yang karena alasan keamanan. GC Javascript adalah 100 ms atau bahkan di atas, yang baik untuk aplikasi umum, tetapi untuk game JS, aplikasi yang membutuhkan koherensi tinggi merepotkan. Inilah yang dibutuhkan mesin baru untuk mengoptimalkan: menghindari respons penghentian jangka panjang yang disebabkan oleh GC.
3) Strategi Optimalisasi GC
Paman David terutama memperkenalkan dua solusi optimisasi, dan ini juga merupakan dua solusi optimisasi yang paling penting:
(1) generasi GC)
Ini konsisten dengan ide strategi daur ulang Java. Tujuannya adalah untuk membedakan antara objek "sementara" dan "gigih"; Daur ulang area "objek sementara" yang lebih banyak dan lebih sedikit area "objek bertenor", mengurangi objek yang perlu dilalui setiap kali, sehingga mengurangi waktu yang dihabiskan untuk GC setiap kali. Seperti yang ditunjukkan pada gambar:
Apa yang perlu ditambahkan di sini adalah bahwa untuk objek generasi yang bertenor, ada overhead tambahan: bermigrasi dari generasi muda ke generasi bertenor, dan jika dirujuk, rujukan referensi juga perlu dimodifikasi.
(2) GC tambahan
Gagasan rencana ini sangat sederhana, yaitu untuk "memperlakukan sedikit setiap kali, menangani sedikit waktu berikutnya, dan sebagainya." Seperti yang ditunjukkan pada gambar:
Meskipun solusi ini membutuhkan waktu singkat, ia memiliki banyak gangguan, yang membawa masalah switching konteks yang sering.
Karena setiap solusi memiliki skenario dan kerugian yang berlaku, dalam aplikasi aktual, solusi akan dipilih sesuai dengan situasi aktual.
Misalnya: Ketika rasio (objek/s) rendah, frekuensi eksekusi GC terganggu, dan GC sederhana lebih rendah; Jika sejumlah besar objek "bertahan" untuk waktu yang lama, keuntungan pemrosesan generasi tidak bagus.
Artikel di atas secara komprehensif memahami mekanisme daur ulang pengumpulan sampah Javascirp adalah semua konten yang saya bagikan dengan Anda. Saya harap ini dapat memberi Anda referensi dan saya harap Anda dapat mendukung wulin.com lebih lanjut.