js垃圾回收机制

       JavaScript具有自动垃圾回收机制,对于开发人员来说是无感知的,通常都是浏览器在代码运行中自动进行的。

为什么会有垃圾回收?

       举个例子,人有生老病死,但是人如果不会死亡,那么人口就会不断增长,最终将会超过地球的负载,地球也将崩溃。
       我们开发的程序也是一样,程序运行中如果只在内存中增加变量,不去销毁内存中一些已经无用的变量,那么程序运行到某个时间将会程序内存将会达到一个峰值,程序也将随之崩溃。

可达性

JavaScript中内存管理的主要概念是可达性

可达性值就是指能够以某种方式可访问的值或可用的变量值,他们将会一直保存在内存中,只有程序退出后才会销毁他们。

显而易见,js会有一组常见的可达值:

1、全局变量
2、函数作用域中的变量及参数
3、当前嵌套调用链上的其他函数的变量和参数

这些值称为
任何可以从根访问到变量值都可以认为是“可达值”
举个例子:

var a = {}  // 此时该对象是可放达的
a = null  // 将null赋值给了a,那么最开始赋值给a的变量就再也访问不到了,那他就会被回收 

理解垃圾回收

目前常用的垃圾回收机制包括:标记清除引用计数
标记清除
变量在进入环境时,将这个变量标记为“进入环境”,当环境离开时标记为“离开环境”。垃圾收集器在运行时会给存储在内存中的所有变量加上标记,他会去掉环境中的变量以及被环境中变量引用的变量的标记

永远不能释放进入环境的变量所占用的内存,因为你很难保证在后面不会用到它。

采取标记的方法有很多,你可以选择自己所喜欢的,比如通过翻转字符串等。

举个例子:

let a = 0;
let b = 0;
function A(c){
	A = function(d) {
		console.log(c+d)
	}
	console.log(c++)
}
A(1)
A(2)

标记清除上面的代码过程如下:

  1. 程序开始执行,垃圾收集器标记所有变量:a,b,A,参数c,参数d。
  2. A(1)执行,程序执行栈进入函数A,垃圾收集器将进行标记清除:清除环境变量参数c内部函数A;函数执行结果为1
  3. A(2)执行,程序进入内部函数A,垃圾收集器进行标记清除,清除环境中参数变量d,由于在步骤2中,外部A函数的环境变量参数c的标记被清除,c的内存将不会释放,c在经过步骤2后更新为2,所以此时结果为4;

标记清除是目前运用最广泛的垃圾回收算法。
引用计数
通过跟踪记录每个值被引用的次数。当声明了一个变量并将一个引用类型值赋给该变量时,则这个值的引用次数就是1,如果同一个值又被赋值给另一个变量,则引用次数加1。相反,如果包含对这个值引用的变量又取得了另外一个值,则这个值的引用次数减一,当这个值得引用次数变成0时,则说明没有办法在访问这个值了,因而就可以将其占用的内存空间回收回来。

let a = {name:"CSDN"} //{name:"CSDN"}引用次数为1
let b = a;   // 将a赋值给b,b实际上还是引用的{name:"CSDN"},因此他的引用次数加1变成2;
a = null; // a的引用变成了null,a无法在访问这个对象,该对象的引用次数就降为1;
b = 0; // 同理,b取得了其他值,不再引用该对象,该对象的引用次数此时就降为了0,在此之后该对象就可以被回收了

如果只是上面例子中这种简单的使用看起来似乎没有什么问题,但在实际使用过程中,引用计数将会因为循环引用导致内存始终无法释放。看依稀啊下面的例子:

function problem(){
	let objectA = new Object(); // 该对象记为A,A对象的引用次数此时为1
	let objectB = new Object(); // 该对象记为B,B对象的引用次数此时为1
	objectA.b = objectB; // objectA引用了B对象,B的医用次数就变为2;
	objectB.a = objectA; // objectB引用了A对象,A的医用次数就变为2;
}

可以看到在本例中,当函数执行完毕,两个对象的引用次数都大于0,因此无法释放内存,这就存在了内存泄漏问题。
但如果使用标记清除,在函数开始执行后将会清除objectA与objectB的标记,后面也没有为其添加标记的方法,因此函数执行结束,变量就会被清除。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值