JS环境中分配的内存一般有如下生命周期:
-
内存分配:当我们申明变量、函数、对象,并执行的时候,系统会自动为他们分配内存
-
内存使用:即读写内存,也就是使用变量、函数等
-
内存回收:使用完毕,由垃圾回收机制自动回收不再使用的内存
垃圾回收机制策略
标记清除算法
JavaScript 中最常用的垃圾收集方式是标记清除(mark-and-sweep)。
它的实现原理就是通过判断一个变量是否在执行环境中被引用,来进行标记删除。
垃圾回收器给所有内存变量进行标记,然后去掉执行环境中和被引用的标记,剩余的标记变量是 不会被用到的变量,会被垃圾回收器回收。
这个算法把“对象是否不再需要”简化定义为“对象是否可以获得”。
该算法假定设置一个叫做根(root)的对象(在Javascript里,根是全局对象)。垃圾回收器将
定期从根开始
(在JS中就是全局对象)扫描内存中的对象。凡是能从根部到达的对象,都是还需要使用的
。那些无法由根部出发触及到的对象被标记为不再使用,稍后进行回收。
此算法可以分为两个阶段,一个是标记阶段(mark),一个是清除阶段(sweep)。
-
标记阶段,垃圾回收器会从根对象开始遍历。每一个可以从根对象访问到的对象都会被添加一个标识,于是这个对象就被标识为可到达对象。
-
清除阶段,垃圾回收器会对堆内存从头到尾进行线性遍历,如果发现有对象没有被标识为可到达对象,那么就将此对象占用的内存回收,并且将原来标记为可到达对象的标识清除,以便进行下一次垃圾回收操作。
在标记阶段,从根对象1可以访问到B,从B又可以访问到E,那么B和E都是可到达对象,同样的道理,F、G、J和K都是可到达对象。
在回收阶段,所有未标记为可到达的对象都会被垃圾回收器回收。
何时开始垃圾回收?
通常来说,在使用标记清除算法时,未引用对象并不会被立即回收。取而代之的做法是,垃圾对象将一直累计到内存耗尽为止。当内存耗尽时,程序将会被挂起,垃圾回收开始执行。
补充: 从2012年起,所有现代浏览器都使用了标记-清除垃圾回收算法。所有对JavaScript垃圾回收算法的改进都是基于标记-清除算法的改进,并没有改进标记-清除算法本身和它对“对象是否不再需要”的简化定义。
标记清除算法缺陷
-
那些无法从根对象查询到的对象都将被清除
-
垃圾收集后有可能会造成大量的内存碎片,像上面的图片所示,垃圾收集后内存中存在三个内存碎片,假设一个方格代表1个单位的内存,如果有一个对象需要占用3个内存单位的话,那么就会导致Mutator一直处于暂停状态,而Collector一直在尝试进行垃圾收集,直到Out of Memory。
引用计数算法
这是最初级的垃圾收集算法.现在已经没有浏览器会用这种算法.
此算法把“对象是否不再需要”简化定义为“对象有没有其他对象引用到它
”。如果没有引用指向该对象(零引用),对象将被垃圾回收机制回收。
引用计数的含义是跟踪记录每个值被引用的次数。当声明了一个变量并将一个引用类型值赋给该变量时,则这个值的引用次数就是1。如果同一个值又被赋给另一个变量,则该值的引用次数加1。相反,如果包含对这个值引用的变量又取得了另外一个值,则这个值的引用次数减1。当这个值的引用次数变成0时,则说明没有办法再访问这个值了,因而就可以将其占用的内存空间回收回来。这样,当垃圾收集器下次再运行时,它就会释放那些引用次数为零的值所占用的内存。
引用计数缺陷
该算法有个限制:无法处理循环引用。如果两个对象被创建,并
互相引用,形成了一个循环
。它们被调用之后会离开函数作用域,所以它们已经没有用了,可以被回收了。然而,引用计数算法考虑到它们互相都有至少一次引用,所以它们不会被回收。
Chrome V8回收算法
减少垃圾和回收对性能的影响:
主要注意以下两点:
-
让垃圾回收尽量少地进行,尤其是全堆垃圾回收。这部分我们基本上帮不了什么忙,主要靠v8自己的优化机制.
-
避免内存泄露,让内存及时得到释放. 即下面要讲的如何管理内存,避免内存泄漏
如何管理内存
JS 的内存自动管理一个最主要的问题就是分配给 Web 浏览器的可用内存数量通常比分配给桌面应用程 序的少。
避免策略:
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数前端工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年Web前端开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上前端开发知识点,真正体系化!
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!
如果你觉得这些内容对你有帮助,可以扫码获取!!(备注:前端)
最后
你要问前端开发难不难,我就得说计算机领域里常说的一句话,这句话就是『难的不会,会的不难』,对于不熟悉某领域技术的人来说,因为不了解所以产生神秘感,神秘感就会让人感觉很难,也就是『难的不会』;当学会这项技术之后,知道什么什么技术能做到什么做不到,只是做起来花多少时间的问题而已,没啥难的,所以就是『会的不难』。
我特地针对初学者整理一套前端学习资料,免费分享给大家,戳这里即可免费领取
术能做到什么做不到,只是做起来花多少时间的问题而已,没啥难的,所以就是『会的不难』。
我特地针对初学者整理一套前端学习资料,免费分享给大家,戳这里即可免费领取
[外链图片转存中…(img-Df8vBBQx-1713515011412)]