1. 程式人生 > >js記憶體洩漏的幾種情況

js記憶體洩漏的幾種情況

js記憶體洩露的幾種情況詳細探討

記憶體洩露是指一塊被分配的記憶體既不能使用,又不能回收,直到瀏覽器程序結束,由於瀏覽器垃圾回收方法有bug,會產生記憶體洩露,下面與大家詳細探討下記憶體洩露的幾種情況

記憶體洩露是指一塊被分配的記憶體既不能使用,又不能回收,直到瀏覽器程序結束。在C++中,因為是手動管理記憶體,記憶體洩露是經常出現的事情。而現在流行的C#和Java等語言採用了自動垃圾回收方法管理記憶體,正常使用的情況下幾乎不會發生記憶體洩露。瀏覽器中也是採用自動垃圾回收方法管理記憶體,但由於瀏覽器垃圾回收方法有bug,會產生記憶體洩露。

程式碼塊

1、當頁面中元素被移除或替換時,若元素繫結的事件仍沒被移除,在IE中不會作出恰當處理,此時要先手工移除事件,不然會存在記憶體洩露。

<div id="myDiv"> 
<input type="button" value="Click me" id="myBtn"> 
</div> 
<script type="text/javascript"> 
    var btn = document.getElementById("myBtn"); 
    btn.onclick = function(){ 
        document.getElementById("myDiv").innerHTML = "Processing..."; 
    } 
</script>

應該改成下面:


<div id="myDiv"> 
<input type="button" value="Click me" id="myBtn"> 
</div> 
<script type="text/javascript"> 
var btn = document.getElementById("myBtn"); 
btn.onclick = function(){ 
btn.onclick = null; 
document.getElementById("myDiv").innerHTML = "Processing..."; 
} 
</script> 

或者採用事件委託

<div id="myDiv"> 
<input type="button" value="Click me" id="myBtn"> 
</div> 
<script type="text/javascript"> 
document.onclick = function(event){ 
event = event || window.event; 
if(event.target.id == "myBtn"){ 
document.getElementById("myDiv").innerHTML = "Processing..."; 
} 
} 
</script> 

2,

var a=document.getElementById("#xx"); 
var b=document.getElementById("#xxx"); 
a.r=b; 
b.r=a; 
var a=document.getElementById("#xx"); 
a.r=a; 

對於純粹的 ECMAScript 物件而言,只要沒有其他物件引用物件 a、b,也就是說它們只是相互之間的引用,那麼仍然會被垃圾收集系統識別並處理。但是,在 Internet Explorer 中,如果迴圈引用中的任何物件是 DOM 節點或者 ActiveX 物件,垃圾收集系統則不會發現它們之間的迴圈關係與系統中的其他物件是隔離的並釋放它們。最終它們將被保留在記憶體中,直到瀏覽器關閉。

3,

var elem = document.getElementById('test'); 
elem.addEventListener('click', function() { 
alert('You clicked ' + elem.tagName); 
}); 

這段程式碼把一個匿名函式註冊為一個DOM結點的click事件處理函式,函式內引用了一個DOM物件elem,就形成了閉包。這就會產生一個迴圈引用,即:DOM->閉包->DOM->閉包…DOM物件在閉包釋放之前不會被釋放;而閉包作為DOM物件的事件處理函式存在,所以在DOM物件釋放前閉包不會釋放,即使DOM物件在DOM tree中刪除,由於這個迴圈引用的存在,DOM物件和閉包都不會被釋放。可以用下面的方法可以避免這種記憶體洩露

var elem = document.getElementById('test'); 
elem.addEventListener('click', function() { 
alert('You clicked ' + this.tagName); // 不再直接引用elem變數 
}); 

4,

function bindEvent() 
{ 
var obj=document.createElement("XXX"); 
obj.onclick=function(){ 
//Even if it's a empty function 
} 
} 

閉包非常容易構成迴圈引用。如果一個構成閉包的函式物件被指定給,比如一個 DOM 節點的事件處理器,而對該節點的引用又被指定給函式物件作用域中的一個活動(或可變)物件,那麼就存在一個迴圈引用。
DOM_Node.onevent -


function bindEvent() 
{ 
var obj=document.createElement("XXX"); 
obj.onclick=onclickHandler; 
} 
function onclickHandler(){ 
//do something 
} 

或者在定義事件處理函式的外部函式中,刪除對dom的引用(題外,《JavaScript權威指南》中介紹過,閉包中,作用域中沒用的屬性可以刪除,以減少記憶體消耗。)

function bindEvent() 
{ 
var obj=document.createElement("XXX"); 
obj.onclick=function(){ 
//Even if it's a empty function 
} 
obj=null; 
} 

5,

a = {p: {x: 1}}; 
b = a.p; 
delete a.p; 

執行這段程式碼之後b.x的值依然是1.由於已經刪除的屬性引用依然存在,因此在JavaScript的某些實現中,可能因為這種不嚴謹的程式碼而造成記憶體洩露。所以在銷燬物件的時候,要遍歷屬性中屬性,依次刪除。

6,自動型別裝箱轉換
別不相信,下面的程式碼在ie系列中會導致記憶體洩露

var s=”lalala”; 
alert(s.length); 

s本身是一個string而非object,它沒有length屬性,所以當訪問length時,JS引擎會自動建立一個臨時String物件封裝s,而這個物件一定會洩露。這個bug匪夷所思,所幸解決起來相當容易,記得所有值型別做.運算之前先顯式轉換一下:


var s="lalala"; 
alert(new String(s).length); 

7、某些DOM操作
IE系列的特有問題 簡單的來說就是在向不在DOM樹上的DOM元素appendChild;IE7中,貌似為了改善記憶體洩露,IE7採用了極端的解決方案:離開頁面時回收所有DOM樹上的元素,其它一概不管。

相關推薦

【java記憶體洩漏5情況總結】

記憶體洩漏定義:一個不再被程式使用的物件或變數還在記憶體中佔有儲存空間。由於java的JVM引入了垃圾回收機制,垃圾回收器會自動回收不再使用的物件,瞭解JVM回收機制的都知道JVM是使用引用計數法和可達性分析演算法來判斷物件是否是不再使用的物件,本質都是判斷一個物件是否還被引

js記憶體洩漏情況

js記憶體洩露的幾種情況詳細探討 記憶體洩露是指一塊被分配的記憶體既不能使用,又不能回收,直到瀏覽器程序結束,由於瀏覽器垃圾回收方法有bug,會產生記憶體洩露,下面與大家詳細探討下記憶體洩露的幾種情況 記憶體洩露是指一塊被分配的記憶體既不能使用,又不

可能出現記憶體洩漏情況

定義    簡單來說,記憶體洩漏就是程式在申請一個記憶體空間後沒有釋放,直到程式執行結束後才釋放。這樣看起來似乎沒什麼大問題,但是如果程式會持續執行很長時間(例如伺服器),並且可能在程每次呼叫某個部分的時候都會申請一個記憶體空間,那麼長久以來的後果是可想而知的:當程式

Android中記憶體洩漏情況

1.單例造成的記憶體洩漏; Android中單例模式中的餓漢式寫法如下: public class Example  { private static Example Instance; private Example(Context context) { this.con

JAVA記憶體洩漏情況

Java記憶體洩漏引起的原因:   記憶體洩漏是指無用物件(不再使用的物件)持續佔有記憶體或無用物件的記憶體得不到及時釋放,從而造成記憶體空間的浪費稱為記憶體洩漏。   長生命週期的物件持有短生命週期物件的引用就很可能發生記憶體洩漏,儘管短生命週期物件已經不再需要,但是因

JVM之記憶體溢位的情況以及可以採取的解決方案

開發中遇到過以下三種記憶體溢位的狀況: 一、 java.lang.OutOfMemoryError: Java heap space 二、 java.lang.OutOfMemoryError: PermGen space 三、 java.lang.OutO

Jvm記憶體溢位的情況

1、java堆溢位 java對用於儲存物件的例項,只要不斷的建立物件,並且保證GC Roots到物件之間有可達路徑來避免垃圾回收機制清除這些物件,那麼在物件數量達到最大堆的容量限制之後機會產生記憶體溢

異常、堆記憶體溢位、OOM的情況

1、堆記憶體溢位 【情況一】:   java.lang.OutOfMemoryError: Java heap space:這種是java堆記憶體不夠,一個原因是真不夠,另一個原因是程式中有死迴圈;   如果是java堆記憶體不夠的話,可以通過調整J

Java記憶體溢位的情況

正文本文通過幾段程式碼模擬實際的記憶體溢位異常。文中程式碼都是基於Oracle公司的HotSpot虛擬機器執行的。1. Java堆溢位1.1 模擬場景Java堆用於儲存物件,只要不斷的建立物件,並保證GC Roots到物件之間有可達路徑來避免垃圾回收機制清除這些物件,那麼在物

今天來給大家分析js中this的指向情況

        之前在寫程式碼時遇到this時,總是在考慮應不應該用,原因是當時分不清楚,後來把this的所有情況分析了一遍,其實超級簡單,而且他的使用場景很好,下面我來把他的幾種情況分析一下,如果this分佈太清得小夥伴們可以參考哈~希望對你們有幫助!        與其他

當表名可控的註入遇到了Describe時的情況

影響 bold 求學 ide 構造 完全 card 別名 pre 轉自:http://www.yulegeyu.com/2017/04/16/%E5%BD%93%E8%A1%A8%E5%90%8D%E5%8F%AF%E6%8E%A7%E7%9A%84%E6%B3%A8%E5

[轉]DB2中需要REORG操作的情況

sting line lte font -type compress win rmi col 問題: 在DB2數據庫中,修改完表的結構時,是否需要對表做一個reorg操作才能使表的狀態恢復正常? 答:有以下4種操作,需要對表做reorg操作 1. SET DATA TYPE

Mysql索引會失效的情況分析

status 過程 ges 此外 ont 其中 like hand ext 轉自:http://www.jb51.net/article/50649.htm 在做項目的過程中,難免會遇到明明給mysql建立了索引,可是查詢還是很緩慢的情況出現,下面我們來具體分析下這種

POI導出Excel的情況

scrip equals eth for get write else des tco 第一種:常見導出【已知表頭(長度一定),已知表數據(具體一個對象的集合,並已知對象各個屬性的類型)】第二種:不常見導出【已知表頭(長度不定),已知表數據(沒有具體對象,裝在Strin

MySQL索引失效的情況

模糊 運算 全表掃描 mysq 子節點 葉子節點 數據 都是 記錄 1.索引不存儲null值 更準確的說,單列索引不存儲null值,復合索引不存儲全為null的值。索引不能存儲Null,所以對這列采用is null條件時,因為索引上根本 沒Null值,不能利用到索引,只能全

java.lang.NullPointerException報錯的情況

style == poi 就會 string arr 不存在 判斷 對象 java.lang.NullPointerException報錯的幾種情況: 1.字符串變量未初始化; 2.接口類型的對象沒有用具體的類初始化,比如:   List stuList ;這種情況就會報空

java中出現內存溢出的情況

xss 除了 占用 memory 兩個 存在 text spa 調用 情況一:java.lang.OutOfMemoryError: Java heap space 原因:java堆內存不足,可能是真的不足,也可能是程序中有死循環 方案:1、調整JVM參數-Xms2048m

spring@value取不到值的情況

spring@value取不到值的幾種情一,spring組件重寫構造方法,在構造方法中引用@value為null由於spring實例化順序為先執行構造方法,再註入成員變量,所以序為先執行構造方法,再註入成員變量,所以ing實例化順取值為null解決辦法為:再寫一個常量類,在常量類中引用@value,再在構造方

總結遇到的elasticsearch啟動失敗的情況及解決

elasticsearch1、使用root用戶啟動失敗 在有一次搭建elasticsearch的時候,使用systemctl啟動elasticsearch失敗,然後在bin目錄下面去使用啟動腳本啟動,發現報錯不能用root用戶啟動,報“Caused by: java.lang.RuntimeException

PHP-判斷條件為false的情況

it is als 註意 浮點 條件 tro 其中 條件判斷 lse 1.整型的0 整型的0 在判斷條件時為false <?php $str = 0; if ($str) { echo ‘It is true!‘; } else { echo ‘It