前端垃圾回收机制与内存泄漏

本文探讨了JavaScript的垃圾回收原理,包括引用计数、标记清除和标记整理算法,以及如何避免内存泄漏和堆栈溢出。通过实例讲解和性能优化技巧,帮助开发者理解和提升内存管理效率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

垃圾回收机制

js是使用垃圾回收的语言,执行环境负责在代码执行时管理内存

js是通过自动内存管理实现内存分配和闲置资源的回收

思路:确定哪个变量不会再使用,然后释放它。

垃圾回收是周期性的。

标记清理

首先为所有变量加上标记,然后将处在上下文的标量的标记去掉,之后假如再被加上标记的变量则是需要回收的变量。

引用计数

内存管理

  • 内存:由可读写单元组成,表示一片可操作空间;
  • 管理:人为的去操作一片空间的申请、使用和释放;
  • 内存管理:开发者主动申请空间、使用空间、释放空间;
  • 管理流程:申请-使用-释放

全停顿

如果一个回收GC 需要50ms,则应用逻辑暂停50ms

js的垃圾回收

判断为垃圾的情况

对象不再被引用

对象不能从根上访问

GC算法

常见的GC算法如下:

  • 引用计数
  • 标记清除
  • 标记整理
  • 分代回收

引用计数

引用计数算法优点:

  • 引用计数为零时,发现垃圾立即回收;
  • 最大限度减少程序暂停;

引用计数算法缺点:

  • 无法回收循环引用的对象;
  • 空间开销比较大;

标记清除

核心思想:分标记和清除两个阶段完成。

  1. 遍历所有对象找标记活动对象;
  2. 遍历所有对象清除没有标记对象;
  3. 回收相应的空间。

标记清除算法最大的优点是能够回收循环引用的对象,它也是v8引擎使用最多的算法。

需要引入标记整理的算法

标记整理的缺点是:移动对象位置,不会立即回收对象,回收的效率比较慢。

增量标记

为了减少全停顿时间

性能优化

1.避免使用全局变量

  • 全局变量会挂载在window下;
  • 全局变量至少有一个引用计数;
  • 全局变量存活更久,持续占用内存;
  • 在明确数据作用域的情况下,尽量使用局部变量;

2.减少判断层级

3 减少数据读取次数,缓存

4 减少循环体活动

5 事件绑定优化

6 避开闭包陷阱

堆(heap)与栈(stack)

在JavaScript中简单数据类型是放在栈中的,复杂数据类型是放在堆中的。
基本类型:这些类型在内存中分别占有固定大小的空间,他们的值保存在栈空间,我们通过按值来访问的
引用类型:引用类型,值大小不固定,栈内存中存放地址指向堆内存中的对象。是按引用访问的。

区别

栈(stack)会自动分配内存空间,会自动释放堆(heap)动态分配的内存,大小不定也不会自动释放
堆:队列优先,先进先出;由操作系统自动分配释放 ,存放函数的参数值,局部变量的值等。
栈:先进后出;动态分配的空间 一般由程序员分配释放, 若程序员不释放,程序结束时可能由OS回收,分配方式倒是类似于链表。

堆栈溢出

上边说道栈的数据会自动清除,而堆中的数据不会自动清除,需要手动清除。

每次存储数据,就会造成堆中的东西一直在增加,也就是当存储的数据达到某一限制时,就会造成堆栈溢出。

内存泄漏

当不断的向堆中存储数据,而不进行清理,这就是内存泄漏。(内存泄漏的结果就是堆栈溢出

垃圾回收机制

js中只有自动清理。清理的对象也可以叫做 ‘孤儿对象’ 。(堆中的数据的地址在栈中没有任何引用,这个堆中的数据对象就叫孤儿对象)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值