成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

深入淺出 JavaScript 內(nèi)存管理,垃圾回收

oogh / 2626人閱讀

摘要:可以改成下面代碼手動(dòng)移除事件監(jiān)聽器和變量例四清除定時(shí)器清除變量鏈接觀察垃圾回收是怎么工作的在上面圖片中,可以觀察到,點(diǎn)擊按鈕,內(nèi)存和節(jié)點(diǎn)數(shù)暴增,當(dāng)點(diǎn)擊時(shí),垃圾收集器回收了這些定時(shí)器變量等,從而釋放了內(nèi)存。

簡(jiǎn)介

本篇文章講解JavaScript 中垃圾回收機(jī)制,內(nèi)存泄漏,結(jié)合一些常遇到的例子,相信各位看完后,會(huì)對(duì)JS 中垃圾回收機(jī)制有個(gè)深入的了解。

我的github,歡迎 star

內(nèi)存生命周期

首先,不管什么程序語(yǔ)言,內(nèi)存生命周期基本是一致的:

分配你所需要的內(nèi)存

使用分配到的內(nèi)存(讀、寫)

不需要時(shí)將其釋放歸還

?在所有語(yǔ)言中第一和第二部分都很清晰。最后一步在低級(jí)語(yǔ)言中(C語(yǔ)言等)很清晰,但是在像JavaScript 等高級(jí)語(yǔ)言中,這一步是隱藏的、透明的。因?yàn)镴avaScript 具有自動(dòng)垃圾收集機(jī)制(Garbage collected )。在編寫 JS 時(shí),不需要關(guān)心內(nèi)存使用問(wèn)題,所需內(nèi)存分配以及無(wú)用內(nèi)存的回收完全實(shí)現(xiàn)了自動(dòng)管理。

內(nèi)存泄漏

內(nèi)存泄漏(memory leaks),什么情況下回導(dǎo)致內(nèi)存泄漏?可以簡(jiǎn)單理解為有些代碼本來(lái)要被回收的,但沒(méi)有被回收,還一直占用著操作系統(tǒng)內(nèi)存,從而越積越多,最終會(huì)導(dǎo)致內(nèi)存泄漏(可以理解為,內(nèi)存滿了,就溢出了)。

管理內(nèi)存(Memory Management)

分配給web瀏覽器的可用內(nèi)存數(shù)量通常要比分配給桌面應(yīng)用程序少。這樣做的目的主要是處于安全方面考慮,目的是防止運(yùn)行JS 的網(wǎng)頁(yè)耗盡全部系統(tǒng)內(nèi)存而導(dǎo)致系統(tǒng)崩潰。內(nèi)存限制問(wèn)題不僅會(huì)影響給變量分配內(nèi)存,同時(shí)還會(huì)影響調(diào)用棧以及在一個(gè)線程中能夠同時(shí)執(zhí)行的語(yǔ)句數(shù)量。

因此,確保占用最少的內(nèi)存可以讓頁(yè)面獲得更好的性能。而優(yōu)化內(nèi)存占用的最佳方式,就是為執(zhí)行中的代碼只保存必要的數(shù)據(jù)。一旦數(shù)據(jù)不再有用,最好通過(guò)將其值設(shè)置為 null 來(lái)釋放其引用。這個(gè)方法叫做解除引用。這一做法適用于大多數(shù)的全局變量和全局對(duì)象的屬性。局部變量會(huì)在他們離開執(zhí)行環(huán)境時(shí)自動(dòng)被解除引用。

解除一個(gè)值的引用并不意味著自動(dòng)回收改值所占用的內(nèi)存。解除引用的真正作用是讓值脫離執(zhí)行環(huán)境,以便垃圾收集器下次運(yùn)行時(shí)將其回收。

標(biāo)記清除(Mark and Sweep)

通常,垃圾收集器(garbage collector)在運(yùn)行時(shí)候會(huì)給儲(chǔ)存在內(nèi)存中的所有變量都加上標(biāo)記。然后,它會(huì)去掉環(huán)境中的變量以及被環(huán)境中的變量引用的變量的標(biāo)記。而在此之后再被加上標(biāo)記的變量將被視為準(zhǔn)備刪除的變量,原因是環(huán)境中的變量已經(jīng)無(wú)法訪問(wèn)到這些變量了。最后,垃圾收集器完成內(nèi)存清除的工作。

那標(biāo)記清除具體是如何呢?有以下幾種算法:

在JavaScript 中,全局變量(Global)和window 對(duì)象會(huì)一直存在,不會(huì)被垃圾收集器回收;

遞歸所用到的所有(包括變量和方法),都不會(huì)被回收;

所有沒(méi)有被標(biāo)記為“活躍(active)”的,都會(huì)被認(rèn)為是垃圾,收集器釋放會(huì)回收垃圾,并把內(nèi)存還給操作系統(tǒng)。

例子: 例一:
var n = 123; 
// 給數(shù)值變量分配內(nèi)存

var s = "azerty"; 
// 給字符串分配內(nèi)存

// 給對(duì)象及其包含的值分配內(nèi)存
var o = {
  a: 1,
  b: null
};

// 給函數(shù)(可調(diào)用的對(duì)象)分配內(nèi)存
function f(a){
  return a + 2;
}
例二:
function foo(arg) {
  // 此處bar 是全局變量,window.bar 可以訪問(wèn),所以也不會(huì)被回收
  bar = "this is a hidden global variable";
} 

function foo() {
  // 此處this 代表 window
  this.variable = "potential accidental global";
} 
例三:
var someResource = getData();
setInterval(function() {
  var node = document.getElementById("Node");
  if(node) {
    node.innerHTML = JSON.stringify(someResource));
  }
}, 1000);

// 上面這段代碼,定時(shí)器setInterval 和 someResource 一直存在,不會(huì)被回收。可以改成下面代碼

var element = document.getElementById("button");

function onClick(event) {
    element.innerHtml = "text";
}

element.addEventListener("click", onClick);
// 手動(dòng)移除事件監(jiān)聽器和變量
element.removeEventListener("click", onClick);
element.parentNode.removeChild(element);
例四:
var intervalId = null, params;

function createChunks() {
  var div, foo, i, str;
  for (i = 0; i < 20; i++) {
    div = document.createElement("div");
    str = new Array(1000000).join("x");
      foo = {
        str: str,
        div: div
      };
      div.foo = foo;
  }
}

function start() {
  if (intervalId) {
    return;
  }
  intervalId = setInterval(createChunks, 1000);
}

function stop() {
  if (intervalId) {
    // 清除定時(shí)器
    clearInterval(intervalId);
  }
  // 清除變量
  intervalId = null;
}

鏈接觀察垃圾回收是怎么工作的—Google: Watching the GC work

在上面圖片中,可以觀察到,點(diǎn)擊 start 按鈕,內(nèi)存和節(jié)點(diǎn)數(shù)暴增,當(dāng)點(diǎn)擊stop 時(shí),垃圾收集器回收了這些定時(shí)器、變量等,從而釋放了內(nèi)存。

上期博客

重構(gòu)你的JS代碼

一些CSS3動(dòng)畫

我的github,歡迎star

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/91937.html

相關(guān)文章

  • JavaScript深入淺出第3課:什么是垃圾回收算法?

    摘要:摘要是如何回收內(nèi)存的深入淺出系列深入淺出第課箭頭函數(shù)中的究竟是什么鬼深入淺出第課函數(shù)是一等公民是什么意思呢深入淺出第課什么是垃圾回收算法最近垃圾回收這個(gè)話題非?;?,大家不能隨隨便便的扔垃圾了,還得先分類,這樣方便對(duì)垃圾進(jìn)行回收再利用。 摘要: JS是如何回收內(nèi)存的? 《JavaScript深入淺出》系列: JavaScript深入淺出第1課:箭頭函數(shù)中的this究竟是什么鬼? Jav...

    AaronYuan 評(píng)論0 收藏0
  • 【V8引擎】淺析Chrome V8引擎中的垃圾回收機(jī)制和內(nèi)存泄露優(yōu)化策略

    摘要:一前言的垃圾回收機(jī)制使用垃圾回收機(jī)制來(lái)自動(dòng)管理內(nèi)存。垃圾回收器只會(huì)針對(duì)新生代內(nèi)存區(qū)老生代指針區(qū)以及老生代數(shù)據(jù)區(qū)進(jìn)行垃圾回收。分別對(duì)新生代和老生代使用不同的垃圾回收算法來(lái)提升垃圾回收的效率。 V8 實(shí)現(xiàn)了準(zhǔn)確式 GC,GC 算法采用了分代式垃圾回收機(jī)制。因此,V8 將內(nèi)存(堆)分為新生代和老生代兩部分。 一、前言 V8的垃圾回收機(jī)制:JavaScript使用垃圾回收機(jī)制來(lái)自動(dòng)管理內(nèi)存。垃...

    qingshanli1988 評(píng)論0 收藏0
  • Node.js內(nèi)存管理和V8垃圾回收機(jī)制

    摘要:垃圾回收內(nèi)存管理實(shí)踐先通過(guò)一個(gè)來(lái)看看在中進(jìn)行垃圾回收的過(guò)程是怎樣的內(nèi)存泄漏識(shí)別在環(huán)境里提供了方法用來(lái)查看當(dāng)前進(jìn)程內(nèi)存使用情況,單位為字節(jié)中保存的進(jìn)程占用的內(nèi)存部分,包括代碼本身?xiàng)6选? showImg(https://segmentfault.com/img/remote/1460000019894672?w=640&h=426);作者 | 五月君Node.js 技術(shù)棧 | https:...

    JowayYoung 評(píng)論0 收藏0
  • 淺談V8引擎中的垃圾回收機(jī)制

    摘要:新生代的對(duì)象為存活時(shí)間較短的對(duì)象,老生代中的對(duì)象為存活時(shí)間較長(zhǎng)或常駐內(nèi)存的對(duì)象。分別對(duì)新生代和老生代使用不同的垃圾回收算法來(lái)提升垃圾回收的效率。如果指向老生代我們就不必考慮它了。 這篇文章的所有內(nèi)容均來(lái)自 樸靈的《深入淺出Node.js》及A tour of V8:Garbage Collection,后者還有中文翻譯版V8 之旅: 垃圾回收器,我在這里只是做了個(gè)記錄和結(jié)合 垃圾回收...

    happen 評(píng)論0 收藏0
  • javascript 垃圾回收算法

    摘要:它將堆內(nèi)存一分為二每一部分空間稱為。以的垃圾回收堆內(nèi)存為例做一次小的垃圾回收需要毫秒以上做一次非增量式的垃圾回收甚至要秒以上。這是垃圾回收中引起線程暫停執(zhí)行的時(shí)間在這樣的時(shí)間花銷下應(yīng)用的性能和響應(yīng)能力都會(huì)直線下降。 我們通常理解的 javascript 垃圾回收機(jī)制都停留在表面,會(huì)釋放不被引用變量?jī)?nèi)存,最近在讀《深入淺出node.js》的書,詳細(xì)了解了下 v8 垃圾回收的算法,記錄了一...

    simon_chen 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

閱讀需要支付1元查看
<