红宝书 ? 4.3 垃圾回收
垃圾回收
JavaScript是使用垃圾回收的语言,也就是执行环境负责在代码执行时管理内存。
基本思路 垃圾回收♻️程序每隔一段时间就会运行,找到不被使用的变量,然后释放它的内存。但是,哪个变量不被使用,是不可判定的问题,算法也解决不了。因此,垃圾回收程序会跟踪记录变量的使用状态,如何标记?,在浏览器的发展史上用到过两种标记策略。如下
【标记清理】*
【1】 变量进入上下文(函数内部声明一个变量时),这个变量会被加入上下文的标记?。
加标签的方式例如:
- 进入上下文时,反转某一位
- 维护“在上下文”和“不在上下文”的变量
- 把变量从一个列表移到另一个列表
标记过程的实现并不重要,关键是策略。
【2】 垃圾回收程序运行的时候,会标记?内存中的所有变量。
【3】 去掉上下文中使用和引用的变量的标记?
【4】 仍有标记?的就是待销毁的变量
【5】 垃圾回收♻️程序做一次内存清理,清理掉这些变量并回收内存
了解即可:
各种浏览器在自己的JavaScript实现中采用标记清理,只是在运行回收的频率上有所差异。
【引用计数】
不常用
【思路】:记录每个值的引用次数
例如声明变量a,let a ={"name":"test"}
此时这个值{"name":"test"}
的引用数为1,
把a的这个引用值赋值给blet b = a
,那么值得引用数+1。
类似的,当把这个引用值覆盖调,引用数-1,即b.name="change"
当一个值得引用数为0,这个值就可以安全回收了。
【最后】垃圾回收♻️程序下次运行会释放引用数为0的值得内存
【存在的问题】
function problerm(){
let obja = new Object()
let objb = new Object()
obja.cona = objb
objb.conb = obja
}
两个对象间相互引用,也就是引用数都是2。在引用计数策略下,两个对象在函数结束后还会存在,引用计数不会变成0。调用多次会导致内存永远不会释放。
【性能】
【垃圾回收的时间调度】
垃圾回收程序会周期性运行,如果内存中分配了很多变量,则可能造成性能损失。尤其是移动设备,其内存有限,垃圾回收会拖慢渲染的速度和帧率。我们开发并不知道什么时候会收集垃圾,因此写代码时做到,让它尽快结束。
【何时运行】
垃圾回收程序会基于对JavaScript运行时环境的探测来决定什么时候运行,不同探测引擎机制不同,但基本都是根据已分配对象的大小和数量判断的。
在某些浏览器中,可以主动触发垃圾回收机制但不推荐。如 IE window.CollectGarbage(),Opera的 window.opera.collect()
【内存管理】
开发者通常不需要关心内存。 JavaScript运行在一个内存管理与垃圾回收都很特殊的环境,分配内存排序:桌面软件>浏览器>移动浏览器。这是出于安全考虑,避免大量JavaScript运行耗尽系统内存导致操作系统崩溃。 这个内存限制不仅影响变量分配,也影响调用栈以及能够同时在一个线程中执行的语句数量
相关文章
- 「 【分享】WordPress超美免费主题,高颜值,高性能于一身的极客主题 」
- log4j 1.x 与 logback 的鸡肋RCE讨论
- 「 【折腾】把手机当作电脑扬声器,手机当电脑音响 」
- log4j2 JNDI 注入漏洞分析
- 「 个人网页设计记录-404-not-found篇-菜鸡记录 」
- 「 记录一次google人机认证recaptcha无法显示解决方案 」
- 「 【特别说明】域名变更&本站计划下线关闭amp/mip页面 」
- 「 自写typecho的404错误页面 」
- Thymeleaf SSTI 分析以及最新版修复的 Bypass
- 「 typecho主题向-单纯的课程表主题Qclass 」
- 「 # lost-theme-typecho 」
- 「 Flex弹性布局 (上) 篇 」
- 「 两数之和 」
- 「 记录一次拯救者r7000 2021H安装黑苹果 」
- 「 记录一次 编译qemu7.0并运行win7 」
- 「 c语言输出1-99的同构数 」
- 「 c语言使用起泡法对输入的10个数字进行排序 」
- 「 c语言写出斐波拉契前四十位 」
- 「 给typecho评论添加数字验证码 」
- 「 typecho主题设置pjax无刷新加载 」