Apa itu pengumpulan sampah JavaScript? Apa yang penting bagi seorang programmer web untuk memahami tentang pengumpulan sampah JavaScript, untuk menulis kode yang lebih baik?
297
Apa itu pengumpulan sampah JavaScript? Apa yang penting bagi seorang programmer web untuk memahami tentang pengumpulan sampah JavaScript, untuk menulis kode yang lebih baik?
Jawaban:
Eric Lippert menulis posting blog rinci tentang hal ini beberapa waktu lalu (selain membandingkannya dengan VBScript ). Lebih tepatnya, ia menulis tentang JScript , yang merupakan implementasi ECMAScript dari Microsoft sendiri, meskipun sangat mirip dengan JavaScript. Saya akan membayangkan bahwa Anda dapat mengasumsikan sebagian besar perilaku akan sama untuk mesin JavaScript Internet Explorer. Tentu saja, implementasinya akan bervariasi dari peramban ke peramban, meskipun saya menduga Anda dapat mengambil sejumlah prinsip umum dan menerapkannya ke peramban lain.
Dikutip dari halaman itu:
Tujuan utama pengumpulan sampah adalah agar pemrogram tidak perlu khawatir tentang manajemen memori dari objek yang mereka buat dan gunakan, meskipun tentu saja tidak ada cara menghindarinya kadang-kadang - selalu menguntungkan jika setidaknya memiliki gambaran kasar tentang cara kerja pengumpulan sampah .
Catatan sejarah: revisi jawaban sebelumnya memiliki referensi yang salah kepada
delete
operator. Dalam JavaScript ,delete
operator menghapus properti dari objek , dan sepenuhnya berbeda dengandelete
di C / C ++.sumber
delete
tidak benar; misalnya dalam contoh pertama, alih-alihdelete foo
, Anda harus terlebih dahulu menghapus event listener viawindow.removeEventListener()
dan kemudian gunakanfoo = null
untuk menimpa variabel; di IE,delete window.foo
(tetapi tidakdelete foo
) juga akan bekerja jikafoo
itu global, tetapi meskipun demikian itu tidak akan di FF atau Operadelete
adalah operator unary (ekspresi), bukan pernyataan (yaitu:)delete 0, delete 0, delete 3
. Itu terlihat seperti pernyataan ketika diekspresikan oleh pernyataan ekspresi.Waspadai referensi melingkar ketika objek DOM terlibat:
Pola kebocoran memori dalam JavaScript
Ingatlah bahwa memori hanya dapat direklamasi ketika tidak ada referensi aktif ke objek. Ini adalah perangkap umum dengan penutupan dan penangan acara, karena beberapa mesin JS tidak akan memeriksa variabel mana yang sebenarnya direferensikan dalam fungsi dalam dan hanya menyimpan semua variabel lokal dari fungsi melampirkan.
Berikut ini contoh sederhana:
Implementasi JS yang naif tidak dapat mengumpulkan
bigString
selama event handler ada. Ada beberapa cara untuk mengatasi masalah ini, misalnya pengaturanbigString = null
di akhirinit()
(delete
tidak akan berfungsi untuk variabel lokal dan argumen fungsi:delete
menghapus properti dari objek, dan objek variabel tidak dapat diakses - ES5 dalam mode ketat bahkan akan melemparReferenceError
jika Anda mencoba untuk menghapus variabel lokal!).Saya sarankan untuk menghindari penutupan yang tidak perlu sebanyak mungkin jika Anda peduli untuk konsumsi memori.
sumber
Kutipan yang bagus diambil dari blog
Komponen DOM adalah "sampah yang dikumpulkan", seperti komponen JScript, yang berarti bahwa jika Anda membuat objek di dalam salah satu komponen, dan kemudian kehilangan jejak objek itu, pada akhirnya akan dibersihkan.
Sebagai contoh:
Ketika Anda memanggil fungsi itu, komponen JScript membuat objek (bernama bigArray) yang dapat diakses di dalam fungsi. Segera setelah fungsi kembali, Anda "kehilangan jejak" bigArray karena tidak ada cara untuk merujuknya lagi. Nah, komponen JScript menyadari bahwa Anda telah kehilangan jejaknya, dan bigArray dibersihkan - memorinya diambil kembali. Hal yang sama berfungsi di komponen DOM. Jika Anda mengatakan
document.createElement('div')
, atau sesuatu yang serupa, maka komponen DOM membuat objek untuk Anda. Setelah Anda kehilangan jejak objek itu, komponen DOM akan membersihkan yang terkait.sumber
Sepengetahuan saya, objek JavaScript adalah sampah yang dikumpulkan secara berkala ketika tidak ada referensi yang tersisa untuk objek tersebut. Ini adalah sesuatu yang terjadi secara otomatis, tetapi jika Anda ingin melihat lebih lanjut tentang cara kerjanya, pada tingkat C ++, masuk akal untuk melihat kode sumber WebKit atau V8
Biasanya Anda tidak perlu memikirkannya, di browser yang lebih lama, seperti IE 5.5 dan versi awal IE 6, dan mungkin versi saat ini, penutupan akan membuat referensi melingkar bahwa ketika tidak dicentang akan berakhir memakan memori. Dalam kasus tertentu yang saya maksud tentang penutupan, saat Anda menambahkan referensi JavaScript ke objek dom, dan sebuah objek ke objek DOM yang merujuk kembali ke objek JavaScript. Pada dasarnya itu tidak pernah bisa dikumpulkan, dan pada akhirnya akan menyebabkan OS menjadi tidak stabil di aplikasi uji yang di-loop untuk membuat crash. Dalam praktiknya, kebocoran ini biasanya kecil, tetapi untuk menjaga kode Anda tetap bersih, Anda harus menghapus referensi JavaScript ke objek DOM.
Biasanya adalah ide yang baik untuk menggunakan kata kunci delete untuk segera membatalkan referensi objek besar seperti data JSON yang telah Anda terima kembali dan melakukan apa pun yang perlu Anda lakukan dengannya, terutama dalam pengembangan web seluler. Ini menyebabkan sapuan GC berikutnya untuk menghapus objek itu dan membebaskan memorinya.
sumber
mark-and-sweep
Algoritma gaya yang lebih baru menangani hal ini .pengumpulan sampah (GC) adalah bentuk manajemen memori otomatis dengan menghapus objek yang tidak diperlukan lagi.
setiap proses berurusan dengan memori ikuti langkah-langkah ini:
1 - mengalokasikan ruang memori yang Anda butuhkan
2 - melakukan pemrosesan
3 - kosongkan ruang memori ini
ada dua algoritma utama yang digunakan untuk mendeteksi objek mana yang tidak diperlukan lagi.
Pengumpulan sampah penghitungan referensi : algoritma ini mengurangi definisi "suatu objek tidak diperlukan lagi" menjadi "suatu objek tidak memiliki objek lain yang merujuk padanya", objek akan dihapus jika tidak ada titik referensi untuk itu
Algoritma mark-and-sweep : menghubungkan setiap objek ke sumber root. objek apa pun tidak terhubung ke root atau objek lain. objek ini akan dihapus.
Saat ini sebagian besar browser modern menggunakan algoritma kedua.
sumber
Semua mesin JavaScript memiliki pemulung sendiri, dan mereka mungkin berbeda. Sebagian besar waktu Anda tidak harus berurusan dengan mereka karena mereka hanya melakukan apa yang seharusnya mereka lakukan.
Menulis kode yang lebih baik sebagian besar tergantung pada seberapa baik Anda tahu prinsip-prinsip pemrograman, bahasa dan implementasi tertentu.
sumber
periksa ini
Dalam Javascript Anda tidak peduli tentang alokasi dan deallokasi memori. Seluruh masalah ditanyakan ke penerjemah Javascript. Kebocoran masih dimungkinkan dalam Javascript, tetapi mereka adalah bug dari penerjemah. Jika Anda tertarik dengan topik ini, Anda dapat membaca lebih lanjut di www.memorymanagement.org
sumber
Pada windows Anda dapat menggunakan Drip.exe untuk menemukan kebocoran memori atau memeriksa apakah mem bebas Anda berfungsi.
Ini sangat sederhana, cukup masukkan URL situs web dan Anda akan melihat konsumsi memori dari renderer IE terintegrasi. Kemudian tekan refresh, jika memori meningkat, Anda menemukan kebocoran memori di suatu tempat di halaman web. Tetapi ini juga sangat berguna untuk melihat apakah rutinitas untuk membebaskan memori berfungsi untuk IE.
sumber
Tipe referensi tidak menyimpan objek secara langsung ke dalam variabel yang ditugaskan, jadi variabel objek dalam contoh ini sebenarnya tidak mengandung instance objek. Sebagai gantinya, ia memegang pointer (atau referensi) ke lokasi di memori tempat objek itu ada
jika Anda menetapkan satu variabel ke variabel lain, masing-masing variabel mendapatkan salinan pointer, dan keduanya masih merujuk objek yang sama dalam memori.
dari Prinsip JavaScript Berorientasi Objek - NICHOLAS C. ZAKAS
sumber