V8中的JavaScript的内存管理与垃圾回收

一.内存的生命周期

无论任何语言,内存生命周期大体一致,会分为:分配内存,使用内存,销毁内存三个阶段


内存机制

1.分配

1.1静态内存分配
1.2动态内存分配
区别:
静态内存分配:

  • 数据大小在编译的时候必须是已知的
  • 在编译时执行
  • 分配给栈
  • 先进后出
动静态内存分配区别

2.使用

读写基本变量或对象的属性、传参等操作,都涉及到了内存的使用。

3.释放

对于不再使用的内存,应当及时释放。


二.V8的内存结构

正在运行的程序由某些内存表示,这些内存成为常驻集


V8内存

1.栈内存

栈用于静态内存分配(Static Memory Allocation),它具有以下特点:

  • 操作数据快,因为是在栈顶操作
  • 数据必须是静态的,数据大小在编译时是已知的
  • 多线程应用程序中,每个线程可以有一个栈
  • 堆的内存管理简单,且由操作系统完成
  • 栈大小有限,可能发生栈溢出(Stack Overflow)
  • 值大小有限制

2.堆内存

堆用于动态内存分配(Dynamic Memory Allocation),与栈不同,程序需要使用指针在堆中查找数据。它的特点是:

  • 操作速度慢,但容量大
  • 可以将动态大小的数据存储在此处
  • 堆在应用程序的线程之间共享
  • 因为堆的动态特性,堆管理起来比较困难
  • 值大小没有限制

堆的内存还可以进一步划分:
1.新生代:空间小,并且分为了两个半空间,由Minor GC管理,其中数据存活期短
2.老生代:空间大,由Major GC管理,老生代可以进一步划分为:

  • 旧指针空间:包含的对象中还存在指针,这个指针指向其他对象
  • 旧数据空间:包含的对象中仅有数据

3.大对象空间:这里对象的大小超过了其他空间大小限制
4.代码空间:即时编译器在这里存储已编译的代码块
5.元空间、属性元空间、映射空间:这些空间中的每个空间都包含相同大小的对象,并且对它们指向的对象有某种约束,从而简化了收集。

(页(Page):页是从操作系统分配的连续内存块,以上的空间都由一组组的页构成的。)


三.回收栈内存

V8会通过移动记录当前执行状态的指针来销毁该函数保存在栈中的执行上下文


四.回收堆内存

V8中的垃圾收集器(Garbage Collector),它的工作是:跟踪内存的分配和使用,以便当分配的内存不再使用时,自动释放它。并且,这个垃圾收集器是分代的,也就是说,堆中的对象按其年龄分组并在不同阶段清除。

回收堆内存有两种思路:
1.引用计数法
2.标记清除法

在V8中,使用两个阶段和三种算法来进行GC:
1.Minor GC:针对新生代,使用Scavenger和Cheney’s algorithm两种算法
2.Major GC:针对老生代,使用Mark-Sweep-Compact算法

两种思路:

1.引用计数法:

内存引用(Memory References)是引用计数法中的一个重要概念。在内存管理的上下文中,如果一个对象可以隐式或显式访问另一个对象,则称该对象引用另一个对象。 例如,JavaScript对象能够引用其原型(隐式引用)和其属性的值(显式引用)。

引用计数就是当某个对象的引用计数为0的时候,就把这个对象视为可回收垃圾

缺点:
如果出现循环引用的情况,那么就无法进行垃圾回收了。

function f() {
  var o1 = {};
  var o2 = {};
  o1.p = o2; // o1 references o2
  o2.p = o1; // o2 references o1. This creates a cycle.
}

f();
循环引用

2.标记清除法
标记清除法不再把“对象是否不再被需要”简化为对象是否被引用了,它是从根节点开始寻找节点,并标记可以到达的节点(标记),然后释放没有被标记的节点(清除)。

标记清除法解决了循环引用的问题。在之前的示例代码中,函数调用返回之后,两个对象从全局对象出发无法获取。因此,它们将会被垃圾回收器回收。

const和let具有块级作用域,当块级作用域消失的时候就可以及时回收内存,提高程序运行效率

V8 GC的两个步骤

1.Minor GC

Minor GC是针对新生区的垃圾回收。
Minor GC的整体思路:(这个过程使用到了Scavenger和Cheney’s algorithm。)

  • 新生代分为两个半区,分别为“To-Space”和“from-Space”,我们先不断地在from-Space上分配内存
  • 如果from-Space满了,就触发GC
  • 找出from-Space上的活动对象,如果这个活动对象存活过两个minor GC周期,就把它移到老生代,否则把它们移到To-Space
  • 清空from-Space
  • 转换“To-Space”和“from-Space”的角色
  • 不断重复上述过程

2.Major GC

Scavenger算法中需要涉及数据迁移,因此适用于小数据,但老生区的数据较大,因此不宜采用该种方法。

Major GC针对老生区进行垃圾回收,使用的是Mark-Sweep-Compact算法,思路为:

  • 标记:对堆进行深度优先遍历,标记上所有可到达的对象
  • 清除:所有未被标记的对象的内存地址均为空闲的内存空间,可以用于存储其他对象
  • 压缩:将所有存活的对象移到一起,以减少碎片化,并提高为新对象分配内存的性能

全停顿(stop-the-world GC):这种类型的GC方式也被称为全停顿,因为 JavaScript 是运行在主线程之上的,一旦执行垃圾回收算法,都需要将正在执行的 JavaScript 脚本暂停下来,待垃圾回收完毕后再恢复脚本执行,会造成性能的下降。

V8中采取的解决策略:
1.增量式编程:GC是在多个增量步骤中完成的,而不是一次性
2.并发标记和并发清理/压缩:使用多个帮助线程并发完成的,而不会影响主线程
3.懒清理:指的是延迟处理Page中的垃圾,直到需要内存才进行清理。


V8 GC解决策略

五.如何优化内存的使用

1.不要在循环之中定义函数
2.不要在循环中定义对象
3.清空数组

arr.length=0;

学习链接:
https://juejin.cn/post/6971245488058302477#heading-6
https://juejin.cn/post/6891614154134667272

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,053评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,527评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,779评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,685评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,699评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,609评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,989评论 3 396
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,654评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,890评论 1 298
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,634评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,716评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,394评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,976评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,950评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,191评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,849评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,458评论 2 342

推荐阅读更多精彩内容