js 垃圾回收机制

发布时间 2024-01-11 12:07:49作者: 徐学进

一 、概述

垃圾回收机制是为了防止内存的泄漏(已经不需要的某一块内存还一直存在着),垃圾回收机制就是不停歇的寻找这些不再使用的变量,并且释放掉他所指向的内存。

2、变量的生命周期

变量被声明、赋值(修改)、读取、不需要时释放,是变量的生命周期。js中的变量分为局部变量和全局变量。局部变量在他当前的函数中产生作用,当该函数结束之后,该变量内存会被释放。全局变量一直存在,直到他被销毁或者浏览器关闭。

为了使开发变得简单,JavaScript 是在创建变量(对象,字符串等)时自动进行了分配内存

var n = 123; // 给数值变量分配内存
var s = "jirengu"; // 给字符串分配内存

调用函数也是内存分配

var d = new Date(); // 分配一个 Date 对象

 

3、js的垃圾回收机制分为两种:标记清除和引用计数。标记清除是指当变量进入执行环境(变量声明)的时候,垃圾回收器将该变量进行了标记,当该变量离开环境的时候,将其再度标记,随之删除。引用计数的机制是跟踪某一个值的引用计数,当生命一个变量并且将一个引用类型赋值给变量的时候,引用次数加1,当这个变量指向其他一个引用次数时减一,当他为0时,触发回收机制进行回收。

 

导致内存泄漏的场景

1、当对象仍然存在着引用,即使此对象不再需要了,垃圾回收机制也不会对其进行回收,比如未正确解除事件的监听器和定时器,导致被监听的对象一直被引用,无法被回收。

eg: 使用了addEventListener,不需要时没有使用removeEventListener;使用了setInterval或者setTimeout,不需要时没有使用clearInterval 或 clearTimeOut

2、循环引用,当两个或多个对象相互引用的时候,并且这些对象没有其他的引用关系的时候,即使这些对象不再被使用,垃圾回收机制也无法回收他们。这种情况下,对象之间形成了一个封闭的循环,导致内存泄漏。

let obj1 = {}
let obj2 = {}
obj1.child = obj2
obj2.child = obj1

解决方法为:合理设计对象之间的引用关系,避免对象型变量循环引用,使用弱引用或者断开循环引用的方法来解决。

3、未释放的资源

例如打开的句柄、网络连接、或数据库连接等资源,使用完毕后没有释放,会导致内存泄漏。

网络请求时超时时间过长,请求一直等待,可能导致内存泄漏。解决思路是使用完成操作后,尽量手动断开或设置超时,比如加上timeout属性。