JavaScript的垃圾回收机制

1.概述

1.1 什么是程序中的垃圾?

简单来说,垃圾就是不需要,已经没用的东西。对应程序中,就是当一个变量没有被其他变量或属性引用的时候,该变量就是程序中的垃圾了。那变量又分局部变量和全局变量,它们的生命周期是不同的,释放内存(垃圾回收)的判断也是不同的。

1.2 变量的生命周期

(1)全局变量:
描述:定义在所有函数之外的变量。
生命周期:会持续到浏览器关闭页面

(2)局部变量:
描述:定义在某个函数中的变量
生命周期:函数执行过后就结束了,此时便可释放它们占用的内存(垃圾回收)

1.3 数据存储

在Javascript中,基本数据类型存储在栈内存中,引用数据类型存储在堆内存中,但是引用数据类型会在栈内存中存储一个实际对象的引用。示例如下:

let num = 12;
let obj = {
   
   name:'shier', age:'12'};
obj = [1,2,3,4];

变量obj和name的存储方式如下图:
在这里插入图片描述

如上图中所示粉色块内数据没有被引用变成了垃圾。

1.4 为什么需要垃圾回收

由于 JavaScript 是动态分配内存的语言,当创建变量、对象、函数等时,都会占用一定的内存。如果这些占用的内存长期不被释放,就会造成内存泄漏,最终可能导致程序崩溃或性能问题。因此,垃圾回收的核心作用就是自动检测不再使用的内存并释放它们,以保持程序的高效运行。

1.5 什么是垃圾回收

垃圾回收机制也称Garbage Collection简称GC。在JavaScript中拥有自动的垃圾回收机制,通过一些回收算法,找出不再使用引用的变量或属性,由JS引擎按照固定时间间隔周期性的释放其所占的内存空间。在C/C++中需要程序员手动完成垃圾回收。

1.6 垃圾回收机制会回收哪些垃圾?

当一个对象不在任何地方被引用时(如何判断是否被引用由算法决定,后面会介绍算法),垃圾回收器就需要将这些对象进行标记,并在适当的时机回收它们的内存

以下面这段代码为例:

function myFunction() {
   
   
  const obj = {
   
    foo: "bar" }
  // do something
}

myFunction()

这段代码中的 obj 对象在 myFunction 函数执行之后,就已经没有被引用了,就需要被回收。

但当某个对象从开发角度上来说不再被使用了,却意外的仍然在某个地方被引用,垃圾回收器就无法回收它的内存,就会造成内存泄漏(内存逐渐累积,程序占用的内存越来越多,当超过系统的可用内存时,就会造成程序崩溃)。

比如下面这段代码中 obj 对象就有可能不会被回收(取决于算法):

function myFunction() {
   
   
  const obj = {
   
    foo: "bar" }

  setTimeout(() => {
   
   
    console.log(obj.foo)
  }, 1000)
}

myFunction()

因为 obj 作为闭包中的引用传递给了定时器的回调函数,即使 myFunction 执行完毕,由于定时器没有被清除,obj 仍然被定时器回调函数持有引用,就可能导致 obj 不会被垃圾回收。

2.垃圾回收策略

垃圾回收并不是实时的,因为开销比较大,所以垃圾回收器会周期性的释放程序中已经不在被引用的垃圾对象。 那如何判断哪些被引用了,哪些不再被引用?通常会使用以下方法来进行判断。

2.1 引用计数法

该算法的原理是,记录每个对象的引用次数,引用增加时计数器加一,引用减少时减一,当引用计数变为零时,就表示没有任何引用指向该对象了,该对象就可以被回收。

	let a = {
   
   
	    name: "江流",
	    age
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值