文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

Javascript的垃圾回收机制知多少?

2024-12-02 14:34

关注

2 内存管理

在Javascript编程中,内存管理大概分成三个步骤,也是内存的生命周期:

内存的生命周期

与其它手动管理内存的语言不一样的是,在Javascript中,当我们创建变量时,系统会给对象进行自动分配对应的内存空间以及闲置资源回收,也就是不需要我们手动进行分配。但是,正是因为垃圾回收机制导致开发者有着错误的感觉,就是他们不用关心内存管理。

  1. const name = "yichuan";//给字符串分配栈内存 
  2. const age = 18;//给数值分配栈内存 
  3.  
  4. //给对象以及包含的值分配堆内存 
  5. const user = { 
  6.   name"onechuan"
  7.   age: 19 
  8. //给数组以及包含的值分配堆内存 
  9. const arr = ["yichuan","onechuan",18]; 
  10. //给函数对象分配堆内存 
  11. function sum(x,y){ 
  12.   return x + y; 

在前面《Javascript的数据类型知多少》文中,我们知道了基础数据类型和引用数据类型的分配机制,即:

栈内存中的基本数据类型,可以直接通过操作系统进行处理,而堆内存中的引用数据类型的值大小不确定,因此需要JS的引擎通过垃圾回收机制进行处理。

3 内存回收机制(GC)

Javascript的V8引擎被限制了内存的使用,因此根据不同操作系统的内存大小会不一样。

V8引擎最初设计是作为浏览器的引擎,并未考虑占据过多的内存空间,随着web技术工程化的发展,占据了越来越多的内存空间。又由于被v8的会回收机制所限制,这样就引起了js执行的线程被挂起,会影响当前执行的页面应用性能。

垃圾回收算法:就是垃圾收集器按照固定的时间间隔,周期性地寻找那些不再使用的变量,然后将其清楚或释放内存。但是垃圾回收算法是个不完美的方案,因为某块内存是否还可用,属于不可预判的问题,也就意味着单纯依靠算法是解决不了的。还有为什么不是实时的找出无用内存并释放呢?其实很简单,实时开销太大了。

我们知道了垃圾是如何产生的,那么我们应该如何清除呢?在浏览器的发展历史上有两种解决策略:

标记清除

标记清除分为:标记阶段和清除阶段。

首先它会遍历堆内存上所有的对象,分别给它们打上标记,然后在代码执行过程结束之后,对所使用过的变量取消标记。在清除阶段再把具有标记的内存对象进行整体清除,从而释放内存空间。

整个标记清除算法大致过程就像下面这样

使用标记清除策略的最重要的优点在于简单,无非是标记和不标记的差异。通过标记清除之后,剩余的对象内存位置是不变的,也会导致空闲内存空间是不连续的,这就造成出现内存碎片的问题。内存碎片多了后,如果要存储一个新的需要占据较大内存空间的对象,就会造成影响。对于通过标记清除产生的内存碎片,还是需要通过标记整理策略进行解决。

简而言之:

标记整理

经过标记清除策略整理后,老生代内存中因此产生了许多内存碎片,如果不进行清理内存碎片,就会对存储造成影响。

标记整理(Mark-Compact)算法 就可以有效地解决标记清除的两个缺点。它的标记阶段和标记清除算法没有什么不同,只是标记结束后,标记整理算法会将活着的对象(即不需要清理的对象)向内存的一端移动,最后清理掉边界的内存。

引用计数

引用计数是一种不常见的垃圾回收策略,其思路就是对每个值都记录其的引用次数。具体的:

  1. let a = new Object()  // 此对象的引用计数为 1(a引用) 
  2. let b = a   // 此对象的引用计数是 2(a,b引用) 
  3. a = null    // 此对象的引用计数为 1(b引用) 
  4. b = null    // 此对象的引用计数为 0(无引用) 
  5. ...   // GC 回收此对象 

这种回收策略看起来很方便,但是当其进行循环引用时就会出现问题,会造成大量的内存不会被释放。当函数结束后,两个对象都不在作用域中,A 和 B 都会被当作非活动对象来清除掉,相比之下,引用计数则不会释放,也就会造成大量无用内存占用,这也是后来放弃引用计数,使用标记清除的原因之一。

4 V8对于垃圾回收机制的优化

大多数浏览器都是基于标记清除算法,不同的只是在运行垃圾回收的频率具有差异。V8 对其进行了一些优化加工处理,那接下来我们主要就来看 V8 中对垃圾回收机制的优化。

分代式垃圾回收

V8 的垃圾回收策略主要基于分代式垃圾回收机制,V8 中将堆内存分为新生代和老生代两区域,采用不同的垃圾回收器也就是不同的策略管理垃圾回收。

新生代的对象为存活时间较短的对象,简单来说就是新产生的对象,通常只支持 1~8M 的容量,而老生代的对象为存活事件较长或常驻内存的对象,简单来说就是经历过新生代垃圾回收后还存活下来的对象,容量通常比较大。

V8 整个堆内存的大小就等于新生代加上老生代的内存,对于新老两块内存区域的垃圾回收,V8 采用了两个垃圾回收器来管控。

新生代和老生代

新生代内存回收

在64操作系统下分配为32MB,因为新生代中的变量存活时间短,不太容易产生太大的内存压力,因此不够大也是能够理解。

对于新生代内存的回收,通常是通过Scavenge 的算法进行垃圾回收,就是将新生代内存进行一分为二,正在被使用的内存空间称为使用区,而限制状态的内存空间称为空闲区。

新生代内存回收的原理是:

新生代中的变量如果经过回收之后依然一直存在,那么会放入到老生代内存中,只要是已经经历过一次Scavenge算法回收的,就可以晋升为老生代内存的对象。

老生代内存回收

当然,Scavenge算法也有其适用场景范围,对于内存空间较大的就不适合使用Scavenge算法。此时应该使用Mark-Sweep(标记清除)和Mark-Compact(标记整理)的策略进行老生代内存中的垃圾回收。

首先是标记阶段,从一组根元素开始,递归遍历这组根元素,遍历过程中能到达的元素称为活动对象,没有到达的元素就可以判断为非活动对象。清除阶段老生代垃圾回收器会直接将非活动对象,也就是数据清理掉。

同样的标记清除策略会产生内存碎片,因此还需要进行标记整理策略进行优化。

5 内存泄漏与优化

内存泄漏,指在JS中已经分配内存地址的对象由于长时间未进行内存释放或无法清除,造成了长期占用内存,使得内存资源浪费,最终导致运行的应用响应速度变慢以及最终崩溃的情况。

在代码中创建对象和变量时会占据内存,但是JS基于自己的内存回收机制是可以确定哪些变量不再需要,并将其进行清除。但是,当你的代码中存在逻辑缺陷时,你以为你已经不需要,但是程序中还存在这引用,这就导致程序运行完后并没有进行合适的回收所占有的内存空间。运行时间越长占用内存越多,随之出现的问题就是:性能不佳、高延迟、频繁崩溃。

造成内存泄漏的常见原因有:

关于内存泄漏,如果你想要更好地排查以及提前避免问题的发生,最好的解决方法是通过熟练使用Chrome的内存剖析工具,多分析多定位Chrome帮你分析保留的内存快照,来查看持续占用大量内存的对象。

6 参考文章

7 写在后面

本篇文章聊了JS的内存管理机制,以及v8垃圾回收机制,最后我们也分析了一些日常编码中经常遇到内存泄漏问题,根据不同的原因给出对应的解决方案。

【编辑推荐】

  1. 鸿蒙官方战略合作共建——HarmonyOS技术社区
  2. Windows 11又出新Bug 搜索邮件也会卡死 微软:将解决
  3. 迫于压力 微软宣布恢复Windows 11一键切换默认浏览器选项
  4. Windows 11 通知中心愈发完善,微软还将进一步优化飞行模式
  5. 14种新型浏览器攻击出现,影响谷歌、微软、苹果和火狐浏览器
  6. 微软发布 OneDrive ARM64 预览版,全面适配 Windows 11/10 ARM 和 M1 Mac

 

来源:前端万有引力内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯