久久久久在线观看_又色又爽又黄的免费视频播放_一区中文字幕_日韩电影在线播放

今日焦點 焦點資訊 營銷之道 企業報道 淘寶運營 網站建設 軟件開發 400電話
  當前位置: 首頁 » 資訊 » 軟件開發 » 正文

JS內存管理實例講解

放大字體  縮小字體 發布日期:2018-02-22  來源:企業800網  作者:新格網  瀏覽次數:336  【去百度看看】
核心提示:?JS有完善的內存處理機制,所以之前我們不用特別的去關注這塊的實現。頁面不快了,刷新一下就好了;瀏覽器卡頓,重啟一下就OK。但是隨著SPA和移動APP的流行,以及未來可能存在的PWA的實現,JS內存可能成為新的內存瓶頸。
JS有完善的內存處理機制,所以之前我們不用特別的去關注這塊的實現。頁面不快了,刷新一下就好了;瀏覽器卡頓,重啟一下就OK。但是隨著SPA和移動APP的流行,以及未來可能存在的PWA的實現,JS內存可能成為新的內存瓶頸。

1.什么是內存泄漏

當我們決定不再使用某些內存時,由于錯誤的編碼,未能使得GC(Gabbage Collection)正確的將這些內存回收的情況,就是內存泄漏。

2.內存的占用,分配和回收

2.1 內存的占用


一個對象占用的內存分為直接占用內存(Shallow Size)和占用總內存(Retained Size)。

直接占用內存:對象本身占用的內存。典型的Javascript對象都會有保留內存用來描述這個對象和存儲它的直接值。一般,只有數組和字符串會有明顯的直接占用內存(Shallow Size)。但字符串和數組常常會在渲染器內存中存儲主要數據部分,僅僅在Javascript對象棧中暴露一個很小的包裝對象。
占用總內存:直接占用內存和這個引用的依賴對象所占用的內存。

賦值和New操作都會涉及到內存的占用。

2.2 內存的分配

Chrome V8的垃圾回收(GC)算法基于Generational Collection,內存被劃分為兩種,分別稱為Young Generation(YG)和Old Generation(OG)。

所謂Young和Old是根據他們占用的時間來劃分的。內存在YG的分配和回收快而頻繁,一般存在的時間很短,所以稱為Young;而在OG中則慢而少發生,所以稱為Old。

因為在V8中,YG的GC過程會阻塞程序,而OG的GC不會阻塞。所以通常情況下開發者更關心YG的細節。

YG又被平分為兩部分空間,分別稱為From和To。所有內存從To空間被分配出去,當To滿時,開始觸發GC,接下來細看一下。

某時刻,To已經分A、B和C分配了內存,當前它剩下一小塊內存未分配出去,而From所有的內存都空閑著。

此時,一個程序需要為D分配內存,但D需要的內存大小超出了To未分配的內存,如下圖。此時,觸發GC,頁面停止執行。

接著From和To進行對換,即原來的To空間被標志為From,From被標志為To。并且把活的變量值(例如B)標志出來,而”垃圾“(例如AC)未被標志,它們將會被清掉。

活的B會被復制到To空間,而「垃圾」AC則被回收,同時,D被分配到To空間,最后成下圖的分布

至此,整個GC完成,此過程中頁面停止執行,所以要盡可能的快。當YG中的值存活比較久時,它會被推向OG,OG的空間滿時,觸發OG內的GC,OG的GC時會觸發YG的GC。

  • 每次分配都使To的可用空間減小,程序又更接近GC

  • YG的GC會阻塞程序,所以GC時間不宜太長10ms以內,因為16ms就會出現丟幀;GC不宜太頻繁

  • 某個值變成垃圾后,不會立馬釋放內存,只有在GC的時候所占內存才會被回收。

2.2 內容均來自參考文獻

2.3 內存的回收

GC Root是內存的根結節,在瀏覽器中它是window,在NodeJS中則是global對象。

從GC Root開始遍歷圖,所有能到達的節點稱為活節點,如果存在GC Root不能到達的節點,那么該節點稱為“垃圾”,將會被回收,如圖中灰色的節點。

至于根節點的回收,不受用戶的控制。

3. 導致內存泄漏的原因

3.1 沒有完全切斷與GC root之間的路徑

因為沒有完全切斷與根節點之間的路徑,導致自動GC不會回收這部分內存,從而造成內存泄漏。

具體的原因有:

  • 對象之間的相互引用

var a, b;
a.reference = b;
b.reference = a;
  • 錯誤使用了全局變量

a = "1234567";
相當于
window.a = "1234567";
  • DOM元素清空或刪除時,綁定的事件未清除

<p id="myp">
<input type="button" value="Click me" id="myBtn">
</p>

<script type="text/javascript">
var btn = document.getElementById('myBtn');
btn.onclick = function () {
document.getElementById('myp').innerHTML = 'Processing...';

// btn.onclick = null;
};
</script>
  • 閉包引用

function bindEvent() {
var obj = document.getElementById('xxx');

obj.onclick = function () {

};


// obj = null;
}
  • DOM元素清空或刪除時,子元素存在JS引用,導致子元素的所有父元素都不會被刪除

// b是a的子dom節點, a是body的子節點
var aElement = document.getElementById("a");
var bElement = document.getElementById("b");
document.body.removeChild(aElement);
// aElement = null;
// bElement = null;

3.2 過度占用了內存空間

更多的出現在nodejs中,例如:

  • 無節制的循環

while(1) {
// do sth
}
  • 過大的數組

var arr = [];
for (var i=0; i< 100000000000; i++) {
var a = {
'desc': 'an object'
}
arr.push(a);
}

相關推薦:

詳細介紹Linux中的內存管理

php內存管理之垃圾回收機制的詳解(圖)

如何避免Javascript的內存泄露及內存管理技巧

以上就是JS內存管理實例講解的詳細內容,更多請關注php中文網其它相關文章!

 
 
[ 資訊搜索 ]  [ 加入收藏 ]  [ 告訴好友 ]  [ 打印本文 ]  [ 違規舉報 ]  [ 關閉窗口 ]

 
0條 [查看全部]  相關評論

 
網站首頁 | 關于我們 | 聯系方式 | 使用協議 | 版權隱私 | 網站地圖 | 排名推廣 | 廣告服務 | 積分換禮 | 網站留言 | RSS訂閱 | 皖ICP備2021004516號-14
企業800網 · 提供技術支持