Semasa pembangunan baru-baru ini, saya menggunakan kemas kini separa berjadual pada halaman Akibatnya, semuanya normal di bawah IE6, 7 dan Firefox Namun, selepas beberapa jam di bawah IE8, penyemak imbas ranap, menunjukkan limpahan memori menyangka ia adalah kebocoran ingatan yang disebabkan oleh kod yang ditulis dengan buruk, tetapi IE6 dan 7 adalah perkara biasa Selepas beberapa penyiasatan, ternyata ia adalah pepijat dalam IE8.
Masalah
Dalam IE8, memori yang diduduki dengan menjana nod Dom tertentu tidak akan dikeluarkan, walaupun nod ini dipadamkan, memori tidak akan dikeluarkan.
Jenis nod kebocoran memori termasuk: bentuk, butang, input, pilih, textarea, a, img dan objec
Kebanyakan jenis nod lain tidak akan bocor, seperti span, div, p, table, dsb.
Masalah ini hanya berlaku dalam IE8 dan tidak berlaku dalam pelayar lain.
Jika pengguna menekan F5, IE8 akan memuat semula halaman Pertama, ia akan memunggah window.top, yang akan melepaskan memori. Jika halaman itu ialah iframe, nyahmuat iframe ini dan tiada apa yang akan berlaku. Nampaknya memori akan dikeluarkan hanya apabila window.top dipunggah.
Contoh
Contoh 1
Apabila anda melaksanakan kod berikut, IE8 akan membocorkan memori.
function leak1() { var node = document.getElementById("TO_AREA"); node.innerHTML = "<img />"; node.innerHTML = ""; node = null; }
Nota:
* Contoh ini menambah nod, jadi ia akan bocor.
* Terdapat div in dengan id "TO_AREA".
* Sekadar peringatan, tiada penutupan atau rujukan pekeliling di sini.
Contoh 2
Kod berikut tidak menggunakan innerHTML, tetapi ia masih akan bocor
function leak2() { var node = document.getElementById("FROM_AREA").cloneNode(true); node.id = "NEW_AREA"; document.body.appendChild(node); document.body.removeChild(node); node = null; }
Nota:
* FROM_AREA ialah id borang dan tiada penutupan atau rujukan pekeliling di sini.
Contoh 3
Ini adalah contoh paling mudah dan langsung:
function leak4() { var node = document.createElement("IMG"); document.body.appendChild(node); document.body.removeChild(node); }
Nota:
* Jika span digunakan dan bukannya img, tidak akan berlaku kebocoran.
Contoh ini hanya membocorkan memori dalam IE8, saya telah mengujinya pada IE8 dalam Windows XP, Windows Vista, Windows Server 2008, Windows Server 2008 R2 dan Windows 7, dan menggunakan mod keserasian dan piawaian IE7 dalam IE8 setiap kes.
Halaman ujian
Mengenai kebocoran
Saiz memori berkembang dari semasa ke semasa, tetapi ini tidak langsung menyebabkan penyemak imbas ranap. Nampaknya terdapat had atas memori yang digunakan oleh penyemak imbas Nampaknya mengehadkan memori yang digunakan oleh DHTML melalui beberapa cara dalaman.
Selepas memori mencapai had atas, penyemak imbas akan mengendalikannya secara automatik, seperti muncul kotak dialog yang menunjukkan memori tidak mencukupi.
Selepas ujian saya sendiri, saya mendapati IFrame juga mengalami masalah ini (di bawah IE8)
Tambahan: keluaran memori iframe
Jawapan pembangun teras Ext Jack ialah TabPanelItem tidak akan melakukan pemprosesan khas untuk elemen yang disesuaikan dengan tab apabila bahagian kerja ini mesti diselesaikan di luar kawalan. Sebaliknya, maklumat yang berkaitan menyatakan bahawa IE mempunyai pepijat dalam kitar semula elemen iframe Dalam keadaan biasa, nilai atribut src elemen harus diubah suai kepada "abort:blank" dan dialih keluar secara manual daripada pepohon DOM, dan kemudian. Dengan menetapkan pembolehubah yang merujuknya dalam skrip kepada kosong dan memanggil CollectGarbage(), anda boleh mengelakkan kebocoran memori yang disebabkan oleh iframe tidak dikitar semula dengan betul.
<script> function clearRAM() { var frame = document.getElementById("ifr_content"); frame.src = 'about:blank'; frame.contentWindow.document.write( '');//清空frame的内容 frame.contentWindow.document.clear(); frame.contentWindow.close(); //避免frame内存泄漏 if (navigator.userAgent.indexOf('MSIE') >= 0) { if (CollectGarbage) { CollectGarbage(); //IE 特有 释放内存 //删除原有标记 var tags = document.getElementById("ifrSet"); tags.removeChild(frame); //添加frameset框架 var _frame = document.createElement('frame'); _frame.src = ''; _frame.name = 'content'; _frame.id = 'ifr_content'; tags.appendChild(_frame); } } } //主动释放 5秒一次 setInterval( function() { if (navigator.userAgent.indexOf('MSIE') >= 0) { if (CollectGarbage) { //alert(1) CollectGarbage(); //IE 特有 释放内存 } } }, 5000) </ script>