垃圾回收与内存泄漏

一.垃圾回收

清早起来先给小粉来一波福利~

垃圾回收机制

  • 浏览器的JavaScript具有自动垃圾回收机制,执行环境会负责管理代码执行过程中使用的内存;
  • 原理:垃圾收集器会定期(周期性)找出那些不在继续使用的变量,释放其内存。但是这个过程不是实时的,因为其开销比较大并且GC时停止响应其他操作,所以垃圾回收器会按照固定的时间间隔周期性的执行。

只有函数内的变量才可以被垃圾回收机制回收

1.1 方法

1.1.1 标记清除

1.1.1.1 定义
标记清除是最常用的一种垃圾回收方式。当变量进入环境时,将函数中定义的这个变量标记为“进入环境”,当变量离开环境时,则将其标记为“离开环境”。
1.1.1.2 示例
function test(){
//只对函数中的变量而言,函数中的变量会存在垃圾回收机制
var a = 10 ;       // 标记为进入环境 
var b = 20 ;       // 被标为进入环境
}
test();            // 执行完毕 a、b被标记离开环境,被垃圾回收机制回收

1.1.2 引用计数

1.1.2.1 定义

跟踪记录每个值被引用的次数。

1.1.2.2 标记过程
  • 当声明了一个变量并将一个引用类型值赋给该变量时,则这个值的引用次数就是1。
  • 如果同一个值又被赋给另一个变量,则该值的引用次数加 1。相反,如果包含对这个值引用的变量又取得了另外一个值,则这个值的引用次数减 1。
  • 当这个值的引用次数变成 0 时,则说明没有办法再访问这个值了,因而就可以将其占用的内存空间回收回来。这样,当垃圾回收器下次再运行时,它就会释放那些引用次数为 0 的值所占用的内存。
1.1.2.3 示例:
function test() {
    var a = {};    // a的引用次数为1
    var b = a;     // a的引用次数加1,为2
    var c = a;     // a的引用次数再加1,为3
    var b = {};    // a的引用次数减1,为2(引用的变量又取得了另外一个值)
}

二.内存泄漏

2.1 定义

程序运行是需要内存的,只要程序提出要求,操作系统或者运行时就必须供给内存。对于持续运行的服务进程,必须及时释放不再使用的内存。否则,内存占用越来越高,轻则影响系统性能,重则导致进程崩溃。

不再使用的内存,不及时释放,就会造成内存泄漏

2.2 分类

  • vue中的内存泄漏
  • JS中的内存泄漏

2.2.1 Vue中的内存泄漏

1.如果在mounted/created钩子函数中使用 JS 绑定了DOM/BOM对象中的事件,需要在 beforeDestroy中做对应解绑处理;

mounted() {
   const box = document.getElementById('time-line')
   this.width = box.offsetWidth
   this.resizefun = () => {
     this.width = box.offsetWidth
   }
   window.addEventListener('resize', this.resizefun)
 },
 beforeDestroy() {
   window.removeEventListener('resize', this.resizefun)
   //事件解绑
   this.resizefun = null
 }

2.如果在 mounted/created钩子函数中使用了第三方库初始化,需要在 beforeDestroy中做对应销毁处理(一般用不到,因为很多时候都是直接在全局中 Vue.use,在AAP.vue中注入);
3.如果组件中使用了 setInterval,需要在 beforeDestroy中做对应销毁处理;

2.2.2 JS中的内存泄漏

  1. 循环引用

一个DOM对象被一个Javascript对象引用,与此同时又引用同一个或其它的Javascript对象,这个DOM对象可能会引发内存泄露。这个DOM对象的引用将不会在脚本停止的时候被垃圾回收器回收。要想破坏循环引用,引用DOM元素的对象或DOM对象的引用需要被赋值为null。

  • Dom对象:文档对象模型简称DOM,是W3C组织推荐的处理可扩展置标语言的标准编程接口。
    ★DOM实际上是以面向对象方式描述的文档模型。
    ★DOM定义了表示和修改文档所需的对象、这些对象的行为和属性以及这些对象之间的关系。
    ★通过DOM,可以访问所有的 HTML 元素,连同它们所包含的文本和属性。可以对其中的内容进行修改和删除,同时也可以创建新的元素。
    ★DOM 独立于平台和编程语言。它可被任何编程语言。例如Java、JavaScript 和VBScript 使用。
    ★DOM对象,即是我们用传统的方法(javascript)获得的对象。
    ★DOM准确说是对文档对象的一种规范标准(文档对象模型),标准只定义了属性和方法行为。
  • JavaScript对象
    ★JavaScript 提供多个内建对象,比如 String、Date、Array 等等。
    ★对象只是带有属性和方法的特殊数据类型。
    ★通过js获取的DOM对象就是js对象当浏览器支持js的dom接口(api)时,这里狭义的dom对象是以js对象的形式出现的,也就是一个js对象。
  1. 闭包

在闭包中引入闭包外部的变量时,当闭包结束时此对象无法被垃圾回收

  1. DOM泄漏

当原有的COM被移除时,子结点引用没有被移除则无法回收。

var select = document.querySelector;
var treeRef = select('#tree');
 
//在COM树中leafRef是treeFre的一个子结点
var leafRef = select('#leaf'); 
var body = select('body');
 
body.removeChild(treeRef);
 
//#tree不能被回收入,因为treeRef还在
//解决方法:
treeRef = null;
 
//tree还不能被回收,因为叶子结果leafRef还在
leafRef = null;
  1. 定时器、计时器泄漏(也是常见的内存泄漏的地方)
for (var i = 0; i < 90000; i++) {
  var buggyObject = {
    callAgain: function() {
      var ref = this;
      var val = setTimeout(function() {
        ref.callAgain();
      }, 90000);
    }
  }
 
  buggyObject.callAgain();
  //虽然你想回收但是timer还在
  buggyObject = null;
}

有没有对垃圾回收与内存泄漏更深入一点呐。
温馨提示:
近日注意保暖啦~我的小可爱们

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值