做爰高潮a片〈毛片〉,尤物av天堂一区二区在线观看,一本久久A久久精品VR综合,添女人荫蒂全部过程av

最新文章專題視頻專題問答1問答10問答100問答1000問答2000關(guān)鍵字專題1關(guān)鍵字專題50關(guān)鍵字專題500關(guān)鍵字專題1500TAG最新視頻文章推薦1 推薦3 推薦5 推薦7 推薦9 推薦11 推薦13 推薦15 推薦17 推薦19 推薦21 推薦23 推薦25 推薦27 推薦29 推薦31 推薦33 推薦35 推薦37視頻文章20視頻文章30視頻文章40視頻文章50視頻文章60 視頻文章70視頻文章80視頻文章90視頻文章100視頻文章120視頻文章140 視頻2關(guān)鍵字專題關(guān)鍵字專題tag2tag3文章專題文章專題2文章索引1文章索引2文章索引3文章索引4文章索引5123456789101112131415文章專題3
問答文章1 問答文章501 問答文章1001 問答文章1501 問答文章2001 問答文章2501 問答文章3001 問答文章3501 問答文章4001 問答文章4501 問答文章5001 問答文章5501 問答文章6001 問答文章6501 問答文章7001 問答文章7501 問答文章8001 問答文章8501 問答文章9001 問答文章9501
當(dāng)前位置: 首頁(yè) - 科技 - 知識(shí)百科 - 正文

JavaScript程序中內(nèi)存泄漏的圖文代碼詳細(xì)介紹

來源:懂視網(wǎng) 責(zé)編:小采 時(shí)間:2020-11-27 20:24:17
文檔

JavaScript程序中內(nèi)存泄漏的圖文代碼詳細(xì)介紹

JavaScript程序中內(nèi)存泄漏的圖文代碼詳細(xì)介紹:JavaScript 程序中內(nèi)存泄漏的圖文代碼詳細(xì)介紹:垃圾回收解放了我們,它讓我們可將精力集中在應(yīng)用程序邏輯(而不是內(nèi)存管理)上。但是,垃圾收集并不神奇。了解它的工作原理,以及如何使它保留本應(yīng)在很久以前釋放的內(nèi)存,就可以實(shí)現(xiàn)更快更可靠的應(yīng)用程序。在
推薦度:
導(dǎo)讀JavaScript程序中內(nèi)存泄漏的圖文代碼詳細(xì)介紹:JavaScript 程序中內(nèi)存泄漏的圖文代碼詳細(xì)介紹:垃圾回收解放了我們,它讓我們可將精力集中在應(yīng)用程序邏輯(而不是內(nèi)存管理)上。但是,垃圾收集并不神奇。了解它的工作原理,以及如何使它保留本應(yīng)在很久以前釋放的內(nèi)存,就可以實(shí)現(xiàn)更快更可靠的應(yīng)用程序。在
JavaScript 程序中內(nèi)存泄漏的圖文代碼詳細(xì)介紹:

垃圾回收解放了我們,它讓我們可將精力集中在應(yīng)用程序邏輯(而不是內(nèi)存管理)上。但是,垃圾收集并不神奇。了解它的工作原理,以及如何使它保留本應(yīng)在很久以前釋放的內(nèi)存,就可以實(shí)現(xiàn)更快更可靠的應(yīng)用程序。在本文中,學(xué)習(xí)一種定位 JavaScript 應(yīng)用程序中內(nèi)存泄漏的系統(tǒng)方法、幾種常見的泄漏模式,以及解決這些泄漏的適當(dāng)方法。

簡(jiǎn)介

當(dāng)處理 JavaScript 這樣的腳本語(yǔ)言時(shí),很容易忘記每個(gè)對(duì)象、類、字符串、數(shù)字和方法都需要分配和保留內(nèi)存。語(yǔ)言和運(yùn)行時(shí)的垃圾回收器隱藏了內(nèi)存分配和釋放的具體細(xì)節(jié)。

許多功能無(wú)需考慮內(nèi)存管理即可實(shí)現(xiàn),但卻忽略了它可能在程序中帶來重大的問題。不當(dāng)清理的對(duì)象可能會(huì)存在比預(yù)期要長(zhǎng)得多的時(shí)間。這些對(duì)象繼續(xù)響應(yīng)事件和消耗資源。它們可強(qiáng)制瀏覽器從一個(gè)虛擬磁盤驅(qū)動(dòng)器分配內(nèi)存頁(yè),這顯著影響了計(jì)算機(jī)的速度(在極端的情形中,會(huì)導(dǎo)致瀏覽器崩潰)。

內(nèi)存泄漏指任何對(duì)象在您不再擁有或需要它之后仍然存在。在最近幾年中,許多瀏覽器都改善了在頁(yè)面加載過程中從 JavaScript 回收內(nèi)存的能力。但是,并不是所有瀏覽器都具有相同的運(yùn)行方式。Firefox 和舊版的 Internet Explorer 都存在過內(nèi)存泄漏,而且內(nèi)存泄露一直持續(xù)到瀏覽器關(guān)閉。

過去導(dǎo)致內(nèi)存泄漏的許多經(jīng)典模式在現(xiàn)代瀏覽器中以不再導(dǎo)致泄漏內(nèi)存。但是,如今有一種不同的趨勢(shì)影響著內(nèi)存泄漏。許多人正設(shè)計(jì)用于在沒有硬頁(yè)面刷新的單頁(yè)中運(yùn)行的 Web 應(yīng)用程序。在那樣的單頁(yè)中,從應(yīng)用程序的一個(gè)狀態(tài)到另一個(gè)狀態(tài)時(shí),很容易保留不再需要或不相關(guān)的內(nèi)存。

在本文中,了解對(duì)象的基本生命周期,垃圾回收如何確定一個(gè)對(duì)象是否被釋放,以及如何評(píng)估潛在的泄漏行為。另外,學(xué)習(xí)如何使用 Google Chrome 中的 Heap Profiler 來診斷內(nèi)存問題。一些示例展示了如何解決閉包、控制臺(tái)日志和循環(huán)帶來的內(nèi)存泄漏。

對(duì)象生命周期

要了解如何預(yù)防內(nèi)存泄漏,需要了解對(duì)象的基本生命周期。當(dāng)創(chuàng)建一個(gè)對(duì)象時(shí),JavaScript 會(huì)自動(dòng)為該對(duì)象分配適當(dāng)?shù)膬?nèi)存。從這一刻起,垃圾回收器就會(huì)不斷對(duì)該對(duì)象進(jìn)行評(píng)估,以查看它是否仍是有效的對(duì)象。

垃圾回收器定期掃描對(duì)象,并計(jì)算引用了每個(gè)對(duì)象的其他對(duì)象的數(shù)量。如果一個(gè)對(duì)象的引用數(shù)量為 0(沒有其他對(duì)象引用過該對(duì)象),或?qū)υ搶?duì)象的惟一引用是循環(huán)的,那么該對(duì)象的內(nèi)存即可回收。圖 1 顯示了垃圾回收器回收內(nèi)存的一個(gè)示例。

圖 1. 通過垃圾收集回收內(nèi)存

展示與各個(gè)對(duì)象關(guān)聯(lián)的 root 節(jié)點(diǎn)的 4 個(gè)步驟。

看到該系統(tǒng)的實(shí)際應(yīng)用會(huì)很有幫助,但提供此功能的工具很有限。了解您的 JavaScript 應(yīng)用程序占用了多少內(nèi)存的一種方式是使用系統(tǒng)工具查看瀏覽器的內(nèi)存分配。有多個(gè)工具可為您提供當(dāng)前的使用,并描繪一個(gè)進(jìn)程的內(nèi)存使用量隨時(shí)間變化的趨勢(shì)圖。

例如,如果在 Mac OSX 上安裝了 XCode,您可以啟動(dòng) Instruments 應(yīng)用程序,并將它的活動(dòng)監(jiān)視器工具附加到您的瀏覽器上,以進(jìn)行實(shí)時(shí)分析。在 Windows? 上,您可以使用任務(wù)管理器。如果在您使用應(yīng)用程序的過程中,發(fā)現(xiàn)內(nèi)存使用量隨時(shí)間變化的曲線穩(wěn)步上升,那么您就知道存在內(nèi)存泄漏。

觀察瀏覽器的內(nèi)存占用只能非常粗略地顯示 JavaScript 應(yīng)用程序的實(shí)際內(nèi)存使用。瀏覽器數(shù)據(jù)不會(huì)告訴您哪些對(duì)象發(fā)生了泄漏,也無(wú)法保證數(shù)據(jù)與您應(yīng)用程序的真正內(nèi)存占用確實(shí)匹配。而且,由于一些瀏覽器中存在實(shí)現(xiàn)問題,DOM 元素(或備用的應(yīng)用程序級(jí)對(duì)象)可能不會(huì)在頁(yè)面中銷毀相應(yīng)元素時(shí)釋放。視頻標(biāo)記尤為如此,視頻標(biāo)記需要瀏覽器實(shí)現(xiàn)一種更加精細(xì)的基礎(chǔ)架構(gòu)。

人們?cè)啻螄L試在客戶端 JavaScript 庫(kù)中添加對(duì)內(nèi)存分配的跟蹤。不幸的是,所有嘗試都不是特別可靠。例如,流行的 stats.js 包由于不準(zhǔn)確性而無(wú)法支持。一般而言,嘗試從客戶端維護(hù)或確定此信息存在一定的問題,是因?yàn)樗鼤?huì)在應(yīng)用程序中引入開銷且無(wú)法可靠地終止。

理想的解決方案是瀏覽器供應(yīng)商在瀏覽器中提供一組工具,幫助您監(jiān)視內(nèi)存使用,識(shí)別泄漏的對(duì)象,以及確定為什么一個(gè)特殊對(duì)象仍標(biāo)記為保留。

目前,只有 Google Chrome(提供了 Heap Profile)實(shí)現(xiàn)了一個(gè)內(nèi)存管理工具作為它的開發(fā)人員工具。我在本文中使用 Heap Profiler 測(cè)試和演示 JavaScript 運(yùn)行時(shí)如何處理內(nèi)存。

分析堆快照

在創(chuàng)建內(nèi)存泄漏之前,請(qǐng)查看一次適當(dāng)收集內(nèi)存的簡(jiǎn)單交互。首先創(chuàng)建一個(gè)包含兩個(gè)按鈕的簡(jiǎn)單 HTML 頁(yè)面,如清單 1 所示。

清單 1. index.html
<html>
<head>
 <script src="//ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js" 
type="text/javascript"></script>
</head>
<body>
 <button id="start_button">Start</button>
 <button id="destroy_button">Destroy</button>
 <script src="assets/scripts/leaker.js" type="text/javascript" 
charset="utf-8"></script>
 <script src="assets/scripts/main.js" type="text/javascript" 
charset="utf-8"></script>
</body>
</html>

包含 jQuery 是為了確保一種管理事件綁定的簡(jiǎn)單語(yǔ)法適合不同的瀏覽器,而且嚴(yán)格遵守最常見的開發(fā)實(shí)踐。為 leaker 類和主要 JavaScript 方法添加腳本標(biāo)記。在開發(fā)環(huán)境中,將 JavaScript 文件合并到單個(gè)文件中通常是一種更好的做法。出于本示例的用途,將邏輯放在獨(dú)立的文件中更容易。

您可以過濾 Heap Profiler 來僅顯示特殊類的實(shí)例。為了利用該功能,創(chuàng)建一個(gè)新類來封裝泄漏對(duì)象的行為,而且這個(gè)類很容易在 Heap Profiler 中找到,如清單 2 所示。

清單 2. assets/scripts/leaker.js
var Leaker = function(){};
Leaker.prototype = {
 init:function(){

 } 
};

綁定 Start 按鈕以初始化 Leaker 對(duì)象,并將它分配給全局命名空間中的一個(gè)變量。還需要將 Destroy 按鈕綁定到一個(gè)應(yīng)清理 Leaker 對(duì)象的方法,并讓它為垃圾收集做好準(zhǔn)備,如清單 3 所示。

清單 3. assets/scripts/main.js
$("#start_button").click(function(){
 if(leak !== null || leak !== undefined){
 return;
 }
 leak = new Leaker();
 leak.init();
});

$("#destroy_button").click(function(){
 leak = null;
});

var leak = new Leaker();

現(xiàn)在,您已準(zhǔn)備好創(chuàng)建一個(gè)對(duì)象,在內(nèi)存中查看它,然后釋放它。

  1. 在 Chrome 中加載索引頁(yè)面。因?yàn)槟侵苯訌?Google 加載 jQuery,所以需要連接互聯(lián)網(wǎng)來運(yùn)行該樣例。

  2. 打開開發(fā)人員工具,方法是打開 View 菜單并選擇 Develop 子菜單。選擇 Developer Tools 命令。

  3. 轉(zhuǎn)到 Profiles 選項(xiàng)卡并獲取一個(gè)堆快照,如圖 2 所示。

    圖 2. Profiles 選項(xiàng)卡

    Google Chrome 上的 profiles 選項(xiàng)卡的快照。

  4. 將注意力返回到 Web 上,選擇 Start。

  5. 獲取另一個(gè)堆快照。

  6. 過濾第一個(gè)快照,查找 Leaker 類的實(shí)例,找不到任何實(shí)例。切換到第二個(gè)快照,您應(yīng)該能找到一個(gè)實(shí)例,如圖 3 所示。

    圖 3. 快照實(shí)例

    Heap Profiler 過濾器頁(yè)面的快照

  7. 將注意力返回到 Web 上,選擇 Destroy。

  8. 獲取第三個(gè)堆快照。

  9. 過濾第三個(gè)快照,查找 Leaker 類的實(shí)例,找不到任何實(shí)例。在加載第三個(gè)快照時(shí),也可將分析模式從 Summary 切換到 Comparison,并對(duì)比第三個(gè)和第二個(gè)快照。您會(huì)看到偏移值 -1(在兩次快照之間釋放了 Leaker 對(duì)象的一個(gè)實(shí)例)。

萬(wàn)歲!垃圾回收有效的。現(xiàn)在是時(shí)候破壞它了。

內(nèi)存泄漏 1:閉包

一種預(yù)防一個(gè)對(duì)象被垃圾回收的簡(jiǎn)單方式是設(shè)置一個(gè)在回調(diào)中引用該對(duì)象的間隔或超時(shí)。要查看實(shí)際應(yīng)用,可更新 leaker.js 類,如清單 4 所示。

清單 4. assets/scripts/leaker.js
var Leaker = function(){};

Leaker.prototype = {
 init:function(){
 this._interval = null;
 this.start();
 },

 start: function(){
 var self = this;
 this._interval = setInterval(function(){
 self.onInterval();
 }, 100);
 },

 destroy: function(){
 if(this._interval !== null){
 clearInterval(this._interval); 
 }
 },

 onInterval: function(){
 console.log("Interval");
 }
};

現(xiàn)在,當(dāng)重復(fù) 上一節(jié) 中的第 1-9 步時(shí),您應(yīng)在第三個(gè)快照中看到,Leaker 對(duì)象被持久化,并且該間隔會(huì)永遠(yuǎn)繼續(xù)運(yùn)行。那么發(fā)生了什么?在一個(gè)閉包中引用的任何局部變量都會(huì)被該閉包保留,只要該閉包存在就永遠(yuǎn)保留。要確保對(duì) setInterval 方法的回調(diào)在訪問 Leaker 實(shí)例的范圍時(shí)執(zhí)行,需要將 this 變量分配給局部變量 self,這個(gè)變量用于從閉包內(nèi)觸發(fā) onInterval。當(dāng) onInterval 觸發(fā)時(shí),它就能夠訪問Leaker 對(duì)象中的任何實(shí)例變量(包括它自身)。但是,只要事件偵聽器存在,Leaker 對(duì)象就不會(huì)被垃圾回收。

要解決此問題,可在清空所存儲(chǔ)的 leaker 對(duì)象引用之前,觸發(fā)添加到該對(duì)象的 destroy 方法,方法是更新 Destroy 按鈕的單擊處理程序,如清單 5 所示。

清單 5. assets/scripts/main.js
$("#destroy_button").click(function(){
 leak.destroy();
 leak = null;
});

銷毀對(duì)象和對(duì)象所有權(quán)

一種不錯(cuò)的做法是,創(chuàng)建一個(gè)標(biāo)準(zhǔn)方法來負(fù)責(zé)讓一個(gè)對(duì)象有資格被垃圾回收。destroy 功能的主要用途是,集中清理該對(duì)象完成的具有以下后果的操作的職責(zé):

  • 阻止它的引用計(jì)數(shù)下降到 0(例如,刪除存在問題的事件偵聽器和回調(diào),并從任何服務(wù)取消注冊(cè))。

  • 使用不必要的 CPU 周期,比如間隔或動(dòng)畫。

  • destroy 方法常常是清理一個(gè)對(duì)象的必要步驟,但在大多數(shù)情況下它還不夠。在理論上,在銷毀相關(guān)實(shí)例后,保留對(duì)已銷毀對(duì)象的引用的其他對(duì)象可調(diào)用自身之上的方法。因?yàn)檫@種情形可能會(huì)產(chǎn)生不可預(yù)測(cè)的結(jié)果,所以僅在對(duì)象即將無(wú)用時(shí)調(diào)用 destroy 方法,這至關(guān)重要。

    一般而言,destroy 方法最佳使用是在一個(gè)對(duì)象有一個(gè)明確的所有者來負(fù)責(zé)它的生命周期時(shí)。此情形常常存在于分層系統(tǒng)中,比如 MVC 框架中的視圖或控制器,或者一個(gè)畫布呈現(xiàn)系統(tǒng)的場(chǎng)景圖。

    內(nèi)存泄漏 2:控制臺(tái)日志

    一種將對(duì)象保留在內(nèi)存中的不太明顯的方式是將它記錄到控制臺(tái)中。清單 6 更新了 Leaker 類,顯示了此方式的一個(gè)示例。

    清單 6. assets/scripts/leaker.js
    var Leaker = function(){};
    
    Leaker.prototype = {
     init:function(){
     console.log("Leaking an object: %o", this);
     },
    
     destroy: function(){
    
     } 
    };

    可采取以下步驟來演示控制臺(tái)的影響。

    1. 登錄到索引頁(yè)面。

    2. 單擊 Start。

    3. 轉(zhuǎn)到控制臺(tái)并確認(rèn) Leaking 對(duì)象已被跟蹤。

    4. 單擊 Destroy。

    5. 回到控制臺(tái)并鍵入 leak,以記錄全局變量當(dāng)前的內(nèi)容。此刻該值應(yīng)為空。

    6. 獲取另一個(gè)堆快照并過濾 Leaker 對(duì)象。您應(yīng)留下一個(gè) Leaker 對(duì)象。

    7. 回到控制臺(tái)并清除它。

    8. 創(chuàng)建另一個(gè)堆配置文件。在清理控制臺(tái)后,保留 leaker 的配置文件應(yīng)已清除。

    控制臺(tái)日志記錄對(duì)總體內(nèi)存配置文件的影響可能是許多開發(fā)人員都未想到的極其重大的問題。記錄錯(cuò)誤的對(duì)象可以將大量數(shù)據(jù)保留在內(nèi)存中。注意,這也適用于:

  • 在用戶鍵入 JavaScript 時(shí),在控制臺(tái)中的一個(gè)交互式會(huì)話期間記錄的對(duì)象。

  • console.logconsole.dir 方法記錄的對(duì)象。

  • 內(nèi)存泄漏 3:循環(huán)

    在兩個(gè)對(duì)象彼此引用且彼此保留時(shí),就會(huì)產(chǎn)生一個(gè)循環(huán),如圖 4 所示。

    圖 4. 創(chuàng)建一個(gè)循環(huán)的引用

    該圖中的一個(gè)藍(lán)色 root 節(jié)點(diǎn)連接到兩個(gè)綠色框,顯示了它們之間的一個(gè)連接

    清單 7 顯示了一個(gè)簡(jiǎn)單的代碼示例。

    清單 7. assets/scripts/leaker.js
    var Leaker = function(){};
    
    Leaker.prototype = {
     init:function(name, parent){
     this._name = name;
     this._parent = parent;
     this._child = null;
     this.createChildren();
     },
    
     createChildren:function(){
     if(this._parent !== null){
     // Only create a child if this is the root
     return;
     }
     this._child = new Leaker();
     this._child.init("leaker 2", this);
     },
    
     destroy: function(){
    
     }
    };

    Root 對(duì)象的實(shí)例化可以修改,如清單 8 所示。

    清單 8. assets/scripts/main.js
    leak = new Leaker(); 
    leak.init("leaker 1", null);

    如果在創(chuàng)建和銷毀對(duì)象后執(zhí)行一次堆分析,您應(yīng)該會(huì)看到垃圾收集器檢測(cè)到了這個(gè)循環(huán)引用,并在您選擇 Destroy 按鈕時(shí)釋放了內(nèi)存。

    但是,如果引入了第三個(gè)保留該子對(duì)象的對(duì)象,該循環(huán)會(huì)導(dǎo)致內(nèi)存泄漏。例如,創(chuàng)建一個(gè) registry 對(duì)象,如清單 9 所示。

    清單 9. assets/scripts/registry.js
    var Registry = function(){};
    
    Registry.prototype = {
     init:function(){
     this._subscribers = [];
     },
    
     add:function(subscriber){
     if(this._subscribers.indexOf(subscriber) >= 0){
     // Already registered so bail out
     return;
     }
     this._subscribers.push(subscriber);
     },
    
     remove:function(subscriber){
     if(this._subscribers.indexOf(subscriber) < 0){
     // Not currently registered so bail out
     return;
     }
     this._subscribers.splice(
     this._subscribers.indexOf(subscriber), 1
     );
     }
    };

    registry 類是讓其他對(duì)象向它注冊(cè),然后從注冊(cè)表中刪除自身的對(duì)象的簡(jiǎn)單示例。盡管這個(gè)特殊的類與注冊(cè)表毫無(wú)關(guān)聯(lián),但這是事件調(diào)度程序和通知系統(tǒng)中的一種常見模式。

    將該類導(dǎo)入 index.html 頁(yè)面中,放在 leaker.js 之前,如清單 10 所示。

    清單 10. index.html
    <script src="assets/scripts/registry.js" type="text/javascript" 
    charset="utf-8"></script>

    更新 Leaker 對(duì)象,以向注冊(cè)表對(duì)象注冊(cè)該對(duì)象本身(可能用于有關(guān)一些未實(shí)現(xiàn)事件的通知)。這創(chuàng)建了一個(gè)來自要保留的 leaker 子對(duì)象的 root 節(jié)點(diǎn)備用路徑,但由于該循環(huán),父對(duì)象也將保留,如清單 11 所示。

    清單 11. assets/scripts/leaker.js
    var Leaker = function(){};
    Leaker.prototype = {
    
     init:function(name, parent, registry){
     this._name = name;
     this._registry = registry;
     this._parent = parent;
     this._child = null;
     this.createChildren();
     this.registerCallback();
     },
    
     createChildren:function(){
     if(this._parent !== null){
     // Only create child if this is the root
     return;
     }
     this._child = new Leaker();
     this._child.init("leaker 2", this, this._registry);
     },
    
     registerCallback:function(){
     this._registry.add(this);
     },
    
     destroy: function(){
     this._registry.remove(this);
     }
    };

    最后,更新 main.js 以設(shè)置注冊(cè)表,并將對(duì)注冊(cè)表的一個(gè)引用傳遞給 leaker 父對(duì)象,如清單 12 所示。

    清單 12. assets/scripts/main.js
    	 $("#start_button").click(function(){
     var leakExists = !(
    	 window["leak"] === null || window["leak"] === undefined
    	 );
     if(leakExists){
     return;
     }
     leak = new Leaker();
     leak.init("leaker 1", null, registry);
    });
    
    $("#destroy_button").click(function(){
     leak.destroy();
     leak = null;
    });
    
    registry = new Registry();
    registry.init();

    現(xiàn)在,當(dāng)執(zhí)行堆分析時(shí),您應(yīng)看到每次選擇 Start 按鈕時(shí),會(huì)創(chuàng)建并保留 Leaker 對(duì)象的兩個(gè)新實(shí)例。圖 5 顯示了對(duì)象引用的流程。

    圖 5. 由于保留引用導(dǎo)致的內(nèi)存泄漏

    3 個(gè)方框顯示了 root 節(jié)點(diǎn)與父和子對(duì)象之間的 3 個(gè)不同路徑

    從表面上看,它像一個(gè)不自然的示例,但它實(shí)際上非常常見。更加經(jīng)典的面向?qū)ο罂蚣苤械氖录陕犉鞒3W裱愃茍D 5 的模式。這種類型的模式也可能與閉包和控制臺(tái)日志導(dǎo)致的問題相關(guān)聯(lián)。

    盡管有多種方式來解決此類問題,但在此情況下,最簡(jiǎn)單的方式是更新 Leaker 類,以在銷毀它時(shí)銷毀它的子對(duì)象。對(duì)于本示例,更新destroy 方法(如清單 13 所示)就足夠了。

    清單 13. assets/scripts/leaker.js
    destroy: function(){
     if(this._child !== null){
     this._child.destroy(); 
     }
     this._registry.remove(this);
    }

    有時(shí),兩個(gè)沒有足夠緊密關(guān)系的對(duì)象之間也會(huì)存在循環(huán),其中一個(gè)對(duì)象管理另一個(gè)對(duì)象的生命周期。在這樣的情況下,在這兩個(gè)對(duì)象之間建立關(guān)系的對(duì)象應(yīng)負(fù)責(zé)在自己被銷毀時(shí)中斷循環(huán)。

    結(jié)束語(yǔ)

    即使 JavaScript 已被垃圾回收,仍然會(huì)有許多方式會(huì)將不需要的對(duì)象保留在內(nèi)存中。目前大部分瀏覽器都已改進(jìn)了內(nèi)存清理功能,但評(píng)估您應(yīng)用程序內(nèi)存堆的工具仍然有限(除了使用 Google Chrome)。通過從簡(jiǎn)單的測(cè)試案例開始,很容易評(píng)估潛在的泄漏行為并確定是否存在泄漏。

    不經(jīng)過測(cè)試,就不可能準(zhǔn)確度量?jī)?nèi)存使用。很容易使循環(huán)引用占據(jù)對(duì)象曲線圖中的大部分區(qū)域。Chrome 的 Heap Profiler 是一個(gè)診斷內(nèi)存問題的寶貴工具,在開發(fā)時(shí)定期使用它也是一個(gè)不錯(cuò)的選擇。在預(yù)測(cè)對(duì)象曲線圖中要釋放的具體資源時(shí)請(qǐng)?jiān)O(shè)定具體的預(yù)期,然后進(jìn)行驗(yàn)證。任何時(shí)候當(dāng)您看到不想要的結(jié)果時(shí),請(qǐng)仔細(xì)調(diào)查。

    在創(chuàng)建對(duì)象時(shí)要計(jì)劃該對(duì)象的清理工作,這比在以后將一個(gè)清理階段移植到應(yīng)用程序中要容易得多。常常要計(jì)劃刪除事件偵聽器,并停止您創(chuàng)建的間隔。如果認(rèn)識(shí)到了您應(yīng)用程序中的內(nèi)存使用,您將得到更可靠且性能更高的應(yīng)用程序。

    聲明:本網(wǎng)頁(yè)內(nèi)容旨在傳播知識(shí),若有侵權(quán)等問題請(qǐng)及時(shí)與本網(wǎng)聯(lián)系,我們將在第一時(shí)間刪除處理。TEL:177 7030 7066 E-MAIL:11247931@qq.com

    文檔

    JavaScript程序中內(nèi)存泄漏的圖文代碼詳細(xì)介紹

    JavaScript程序中內(nèi)存泄漏的圖文代碼詳細(xì)介紹:JavaScript 程序中內(nèi)存泄漏的圖文代碼詳細(xì)介紹:垃圾回收解放了我們,它讓我們可將精力集中在應(yīng)用程序邏輯(而不是內(nèi)存管理)上。但是,垃圾收集并不神奇。了解它的工作原理,以及如何使它保留本應(yīng)在很久以前釋放的內(nèi)存,就可以實(shí)現(xiàn)更快更可靠的應(yīng)用程序。在
    推薦度:
    標(biāo)簽: 內(nèi)存 介紹 js
    • 熱門焦點(diǎn)

    最新推薦

    猜你喜歡

    熱門推薦

    專題
    Top
    主站蜘蛛池模板: 穆棱市| 林芝县| 谷城县| 泸溪县| 广州市| 巴东县| 平昌县| 桃源县| 彭州市| 彭阳县| 博客| 大埔县| 腾冲县| 高平市| 锦州市| 宜州市| 潜江市| 遂宁市| 张家川| 多伦县| 宝丰县| 汉寿县| 阿拉善左旗| 巴南区| 长沙市| 台安县| 石景山区| 富川| 延安市| 隆德县| 湄潭县| 内黄县| 东平县| 沙雅县| 百色市| 承德市| 任丘市| 鹤山市| 建德市| 和田县| 武鸣县|