從V8的內存管理算法出發(fā)-教你如何管理內存

@[toc]

導語

  • 什么是V8纺腊?
  • V8 js運行的引擎(類似 java運行在jvm上)
  • 為什么要關注內存畔咧?
  • 防止頁面占用內存過大茎芭,引起客戶端卡頓,甚至無響應誓沸。
  • Node 使用的也是V8梅桩,內存對于后端服務的性能至關重要,因為服務的持久性拜隧,后端更容易造成內存溢出宿百。
  • 面試裝逼神器。

一洪添、V8引擎如何回收垃圾

1垦页、V8的內存分配

在這里插入圖片描述

(1)內存大小

內存的大小和操作系統(tǒng)有關,64位為1.4G干奢,32位為0.7G外臂。

  • 64位下新生代的空間為 64MB ,老生代為 1400MB律胀。
  • 32位下新生代的空間為 16MB 宋光,老生代為 700MB。
  • 為什么只設置 1.4G ? 而不是2G炭菌、3G...
    • 1罪佳、js最初設計是在瀏覽器上跑的,瀏覽器上的js不持久黑低,運行完代碼就可以了赘艳,所以 1.4G 完全夠用。
    • 2克握、js有垃圾回收機制蕾管,回收時會暫停所有代碼的執(zhí)行,(回收300MB大概需要0.5s)菩暗,如果設置為3G掰曾,那回收時間會特別長,程序停止時間過久停团。

(2)新生代和老生代

  • 新生代(semi space From & semi space To)簡單地說就是==復制==
  • 老生代簡單地說就是==標記刪除整理==

新生代:

  • 新生代存放的是 存活時間比較短的變量旷坦,會頻繁發(fā)生垃圾回收。
  • 新生代會標記活著的變量佑稠。首先會將 From 中活著的變量 復制到 To 中秒梅,然后將 From 清空,下一次會將 To 中活著的變量 復制到 From 中舌胶,并將 To 清空捆蜀。
  • 這是典型的 ==犧牲空間,獲取時間== 算法
  • 因為做清空是很快的,而一個一個刪除然后整理是很慢的(內存是連著的辆它,刪除一個變量誊薄,就需要將后面的變量向前復制,然后刪除原來的娩井,整理很慢)

老生代:

  • 老生代會標記死掉的變量,做刪除似袁、整理(碎片整理)的操作洞辣。
  • 數(shù)組是需要連續(xù)的內存空間,整理很耗時間


    在這里插入圖片描述

晉升機制:

  • 剛開始定義的變量都是新生代昙衅,當變量在新生代經歷過一次回收扬霜,就擁有資格晉升為老生代(但不會直接放入老生代)。
  • 直到新生代 To(From) 空間已經使用超過 20% 而涉,那么就會晉升到老生代空間著瓶。

2、變量處理

  • 內存主要就是存儲變量等數(shù)據的
  • 局部變量當程序執(zhí)行結束啼县,且沒有引用的時候就會死掉
  • 全局對象會始終存活到程序運行結束

eg:

function f () {
    var a = ''
}
f(); // f 執(zhí)行結束 a 就會被回收
function f () {
    var a = '';
    return a;
}
var b = f(); // f 執(zhí)行結束 a 不會被回收材原,因為外層作用域還有 a 的引用 b。

二季眷、如何查看V8內存使用情況

1余蟹、使用 node 來查看內存使用情況

  • 通過 process.memoryUsage()
    在這里插入圖片描述

    在這里插入圖片描述
  • rss: V8申請到的總占用空間
  • heapTotal: 堆總內存
  • heapUsed: 已使用的內存
  • external: node專有(底層是c,額外申請到的c++內存 )

2子刮、在 chorme 瀏覽器中查看內存使用情況

  • 通過 window.performance
    在這里插入圖片描述

三威酒、內存優(yōu)化實例

1、優(yōu)化內存技巧

  • (1)盡量不要定義全局變量
  • (2)全局變量記得銷毀掉
  • a = undefined
  • delete a;不建議使用挺峡,嚴格模式下會出問題
  • (3)用匿名自執(zhí)行函數(shù)變全局為局部
  • (function () {}())

eg:

function getme () {
  var mem = process.memoryUsage();
  var format = function (bytes) {
    return (bytes / 1024 / 1024).toFixed(2) + 'MB';
  }
  console.log('heapTotal: ' + format(mem.heapTotal) + 'heapUsed: ' + format(mem.heapUsed));
}
var size = 20 * 1024 * 1024;
var arr1 = new Array(size);
var arr2 = new Array(size);
var arr3 = new Array(size);
var arr4 = new Array(size);
var arr5 = new Array(size);
var arr6 = new Array(size);
var arr7 = new Array(size);
var arr8 = new Array(size);
var arr9 = new Array(size);
getme(); // 內存溢出 極限 8 個
在這里插入圖片描述
function getme () {
  var mem = process.memoryUsage();
  var format = function (bytes) {
    return (bytes / 1024 / 1024).toFixed(2) + 'MB';
  }
  console.log('heapTotal: ' + format(mem.heapTotal) + 'heapUsed: ' + format(mem.heapUsed));
}
var size = 20 * 1024 * 1024;

function a () {
  var arr1 = new Array(size);
  var arr2 = new Array(size);
  var arr3 = new Array(size);
  var arr4 = new Array(size);
  var arr5 = new Array(size);
  var arr6 = new Array(size);
  var arr7 = new Array(size);
  var arr8 = new Array(size);
}
a();
var arr9 = new Array(size);
getme(); // 內存不會溢出

2葵孤、關于閉包和內存使用

首先重要的是:==閉包并不會影響內存==
雖然在某一版(很久遠了)的 《Javascript 權威指南》中作者說過閉包會占用內存,讓盡量避免閉包橱赠。因為當時 IE5 存在這個 BUG 尤仍,所以才導致這個問題。現(xiàn)在的V8是沒有這個問題的狭姨,所以這是錯誤的說法吓著。

eg:

function getme () {
  var mem = process.memoryUsage();
  var format = function (bytes) {
    return (bytes / 1024 / 1024).toFixed(2) + 'MB';
  }
  console.log('heapTotal: ' + format(mem.heapTotal) + 'heapUsed: ' + format(mem.heapUsed));
}

for (let i = 10000; i < 10100; i++) {
  setTimeout(function () {
    console.log(i);
    getme(); // 內存占用 4.x MB
  })
}

// 閉包形式
for (let i = 10000; i < 10100; i++) {
  (function (i) {
    setTimeout(function () {
      console.log(i);
      getme(); // 內存占用 4.x MB
    })
  })(i)
}

碼字不易,覺得有幫助的小伙伴點個贊支持下~


在這里插入圖片描述

掃描上方二維碼關注我的訂閱號~

覺得有幫助的小伙伴點個贊支持下~

?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末送挑,一起剝皮案震驚了整個濱河市绑莺,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌惕耕,老刑警劉巖纺裁,帶你破解...
    沈念sama閱讀 211,639評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡欺缘,警方通過查閱死者的電腦和手機栋豫,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,277評論 3 385
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來谚殊,“玉大人丧鸯,你說我怎么就攤上這事∧坌酰” “怎么了丛肢?”我有些...
    開封第一講書人閱讀 157,221評論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長剿干。 經常有香客問我蜂怎,道長,這世上最難降的妖魔是什么置尔? 我笑而不...
    開封第一講書人閱讀 56,474評論 1 283
  • 正文 為了忘掉前任杠步,我火速辦了婚禮,結果婚禮上榜轿,老公的妹妹穿的比我還像新娘幽歼。我一直安慰自己阱飘,他們只是感情好砸琅,可當我...
    茶點故事閱讀 65,570評論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著棠枉,像睡著了一般设褐。 火紅的嫁衣襯著肌膚如雪颠蕴。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,816評論 1 290
  • 那天助析,我揣著相機與錄音犀被,去河邊找鬼。 笑死外冀,一個胖子當著我的面吹牛寡键,可吹牛的內容都是我干的。 我是一名探鬼主播雪隧,決...
    沈念sama閱讀 38,957評論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼西轩,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了脑沿?” 一聲冷哼從身側響起藕畔,我...
    開封第一講書人閱讀 37,718評論 0 266
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎庄拇,沒想到半個月后注服,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體韭邓,經...
    沈念sama閱讀 44,176評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 36,511評論 2 327
  • 正文 我和宋清朗相戀三年溶弟,在試婚紗的時候發(fā)現(xiàn)自己被綠了女淑。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,646評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡辜御,死狀恐怖鸭你,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情擒权,我是刑警寧澤袱巨,帶...
    沈念sama閱讀 34,322評論 4 330
  • 正文 年R本政府宣布,位于F島的核電站菜拓,受9級特大地震影響瓣窄,放射性物質發(fā)生泄漏笛厦。R本人自食惡果不足惜纳鼎,卻給世界環(huán)境...
    茶點故事閱讀 39,934評論 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望裳凸。 院中可真熱鬧贱鄙,春花似錦、人聲如沸姨谷。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,755評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽梦湘。三九已至瞎颗,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間捌议,已是汗流浹背哼拔。 一陣腳步聲響...
    開封第一講書人閱讀 31,987評論 1 266
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留瓣颅,地道東北人倦逐。 一個月前我還...
    沈念sama閱讀 46,358評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像宫补,于是被迫代替她去往敵國和親檬姥。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 43,514評論 2 348

推薦閱讀更多精彩內容

  • 本文引用自這里這篇文章的所有內容均來自 樸靈的《深入淺出Node.js》及A tour of V8:Garbage...
    楠小忎閱讀 1,413評論 0 2
  • 大多數(shù)時候粉怕,js開發(fā)者其實根本無須接觸垃圾回收機制或內存管理機制等問題健民,因為曾經的js僅僅應用于客戶端瀏覽器(現(xiàn)在...
    LK2917閱讀 1,519評論 0 9
  • 前言 我們知道,JavaScript之所以能在瀏覽器環(huán)境和NodeJS環(huán)境運行贫贝,都是因為有V8引擎在幕后保駕護航荞雏。...
    liuxuan閱讀 484評論 1 1
  • 今天看了一下關于垃圾回收的知識,來總結一下~我們知道,JavaScript之所以能在瀏覽器環(huán)境和NodeJS環(huán)境運...
    Yixi_Li閱讀 626評論 0 1
  • 上一篇文章中凤优,我整理介紹了V8的新生代堆內存的垃圾回收策略悦陋,這里再簡單概述下:V8將堆內存主要劃分為新生代和老生代...
    LK2917閱讀 1,226評論 0 3