JS进阶之内存管理

本篇为JavaScript进阶系列知识点的第一篇博客,只要介绍关于JavaScript的内存管理相关知识,希望通过分享来提升对知识点的认识和自身自控力

一、前端为什么要关注内存

  1. 任何一个程序的运行都需要内存,对于一个页面来说,没有及时释放不再使用的内存,这种现象称为内存泄漏。
  2. 一次内存泄漏似乎影响不大,但内存堆积会造成内存溢出,内存溢出简单来说,我们所需要的内存空间大于可用内存,此时我们的程序就会出现内存溢出错误,造成网页长时间无响应或崩溃。
  3. 本质上讲,内存泄漏就是由于疏忽或错误造成程序未能释放哪些已经不再使用的堆内存,造成内存的浪费。

二、垃圾回收机制

  1. 像C语言这样的底层语言一般都有底层的内存管理接口,比如 malloc()和free()用于分配内存和释放内存。
  2. 而对于JavaScript来说,会在创建变量(对象,字符串等)时分配内存,并且在不再使用它们时“自动”释放内存,这个自动释放内存的过程称为垃圾回收
  3. 找出那些不再继续使用的变量,然后释放其所占用的内存,垃圾回收器会按照的固定时间间隔周期性执行这一操作

三、垃圾回收机制优缺点

  • JavaScript使用垃圾回收机制来自动管理内存,垃圾回收是一把双刃剑;
  1. 优点: 可以大幅简化程序的内存管理代码,降低程序员的负担,减少因长时间运转而带来的内存泄露问题
  2. 缺点: 意味着程序员将无法掌控内存,JavaScript没有暴露任何关于内存的API.我们无法强迫其进行垃圾回收,更无法干预内存管理

四、内存生命周期

在这里插入图片描述

  1. 分配内存: 当我们申明变量、函数、对象时,系统会自动为他们分配内存
  2. 使用内存: 就是使用变量、函数
  3. 释放内存: 使用完毕,由垃圾回收机制自动回收不再使用的内存

五、垃圾回收机制之回收策略

  • 现在各大浏览器通常用采用的垃圾回收有两种方法:标记清除、引用计数

01-引用计数 (reference counting)

  1. 定义: 跟踪记录每个值被引用的次数,如果一个值的引用次数是0,就表示这个值不再用到了,因此可以将这块内存释放
  2. 原理: 每次引用加一,被释放时减一,当这个值的引用次数变成0时,就可以将内存空间回收
  3. 实例:
1 const obj = { a:10 }; // 引用+1 
2 const obj1 = { a:10 }; // 引用+1
3 const obj = {}; //引用减1
4 const obj = null; // 引用为0
  • 过程
    1. 声明了一个变量并将一个引用类型的值赋值给这个变量,这个引用类型的值的引用次数是1
    2. 同一个值又被赋值给另一个变量,这一引用类型值的引用次数加1
    3. 当包含这个引用类型值的变量又被赋值成另一个值了,那么这个引用类型值的引用次数减1
    4. 当引用次数变成0时,说明没办法访问这个值了
    5. 当垃圾收集器下一次运行时,它就会释放引用次数是0的值所占的内存
  1. 存在大问题 – 循环引用无法回收
    // 循环引用
    function fn() {
        var objA = { a: 10 };
        var objB = { b: 10 };
        objA.c = objA;
        objB.d = objB;
    }
    

iE8之前游览器存在这个问题,现在主流游览器几乎采用标记清除

02-标记清除

  1. 定义

    1. 标记清除指的是当变量进入环境时,这个变量标记为 “进入环境”;
    2. 而当变量离开环境时,则将其标记为"离开环境";
    3. 最后,垃圾收集器完成内存清除工作,销毁那些带标记的值并回收他们所占用的内存空间;
    4. 目前主流游览器都是标记清除,只是时间不同
    	function foo () {
        var a = 10; // 被标记进入环境
        var b = 'hello'; // 被标记进入环境
    	}
    	foo(); // 执行完毕,a 和 b 被标记离开环境,内存被回收
    
  2. 执行环境

    • 执行环境定义了变量或函数有权访问的其他数据,决定了他们各自的行为。
    • 每个执行环境都有一个与之关联的变量对象(variable object), 环境中定义的所有变量和函数都保存在这个对象中,
    • 解析器会识别标记这些环境
  3. 全局执行环境

    • 最外围的一个执行环境
    • 根据宿主环境不同表示执行环境的对象不一样。在游览器中,全局执行环境被认为是Window对象
    • 全局变量和函数都是作为window对象的属性和方法创建的
    • 某个执行环境中所有的代码执行完毕后,该环境被销毁,保存在其中的所有变量和函数定义也随之销毁
    • 全局直到应用程序结束,例如: 关闭网页或游览器
  4. 环境栈 (局部)

    • 每个函数都有自己的执行环境。
    • 当执行流进入一个函数时,函数的环境就会被推入一个环境栈中。
    • 而在函数执行之后,栈将其环境弹出,把控制权返回给之前的执行环境。
    • ECMAScript程序中的执行流正是这个方标的机制控制着

六、内存的占用

  • Chrome 浏览器查看内存占用,按照以下步骤操作。
    在这里插入图片描述
1. 打开开发者工具,选择 Memory 面板
2. 点击左上角的录制按钮。
3. 在页面上进行各种操作,模拟用户的使用情况。
4. 一段时间后,点击对话框的 stop 按钮,面板上就会显示这段时间的内存占用情况。

写在最后的话: 自律就是自己知道想要什么,并且足够强烈

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值