当前位置: 首页 > news >正文

js垃圾回收机制

垃圾回收器

  1. js引擎中的一个后台进程----监听所有对象,删除不可访问对象
  2. 在 JavaScript 内存管理中有一个概念叫做 可达性,就是那些以某种方式可访问或者说可用的值,它们被保证存储在内存中,反之不可访问则需回收
/* 案例一 */
let user = {
    name: "John"
};
/* 全局环境 可以通过访问user就可以得到{name:'John'} */
user = null
/* 这样{name:'John'}就不能访问了,就要被回收 */
/* 案例二 */
// user具有对象的引用
let user = {
    name: "John"
};
let admin = user;
/* 全局环境 可以通过访问user或者admin就可以得到{name:'John'} */

user = null
/* 这样{name:'John'}就不能访问了,就要被回收 */
/* 案例三 */
function marry (man, woman) {
    woman.husban = man;
    man.wife = woman;
    return {
        father: man,
        mother: woman
    }
}

let family = marry({
    name: "John"
    }, {
    name: "Ann"
})
/* 如图neicun1 */
delete family.father;
delete family.mother.husband;
/* 如图neicun2 neicun3 neicun4*/
/* John 现在是不可访问的,并将从内存中删除所有不可访问的数据。 */

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

什么是垃圾?

没有被引用的对象,有个例外如果几个对象引用形成一个环,互相引用,但根访问不到它们,这几个对象也是垃圾,也要被清除。

为什么要垃圾回收?

声明变量时,都会分配内存存储,当不再使用时,就要及时释放,否则内存满了造成系统崩溃

标记清除

  1. 当变量进入环境时,就标记这个变量为进入环境
  2. 当变量离开环境时,就标记为离开环境。
  3. 垃圾回收器在运行的时候会给存储在内存中的变量都加上标记(所有都加),然后去掉环境变量中的变量,以及被环境变量中的变量所引用的变量(条件性去除标记),删除所有被标记的变量,删除的变量无法在环境变量中被访问所以会被删除,最后垃圾回收器,完成了内存的清除工作,并回收他们所占用的内存。
  4. 在清除之后,剩余的对象内存位置是不变的,也会导致空闲内存空间是不连续的,出现了 内存碎片,并且由于剩余空闲内存不是一整块,它是由不同大小内存组成的内存列表,这就牵扯出了内存分配的问题
  5. 内存碎片化,空闲内存块是不连续的,容易出现很多空闲内存块,还可能会出现分配所需内存过大的对象时找不到合适的块
  6. 分配速度慢,最坏情况是每次都要遍历到最后,同时因为碎片化,大对象的分配效率会更慢
var a="a";
var b="b";
a = b;

在这里插入图片描述

引用计数

另一种不太常见的方法就是引用计数法,引用计数法的意思就是每个值没引用的次数,当声明了一个变量,并用一个引用类型的值赋值给改变量,则这个值的引用次数为 1,;相反的,如果包含了对这个值引用的变量又取得了另外一个值,则原先的引用值引用次数就减 1,当这个值的引用次数为 0 的时候,说明没有办法再访问这个值了,因此就把所占的内存给回收进来,这样垃圾收集器再次运行的时候,就会释放引用次数为 0 的这些值。

let a = new Object() 	// 此对象的引用计数为 1(a引用)
let b = a 		// 此对象的引用计数是 2(a,b引用)
a = null  		// 此对象的引用计数为 1(b引用)
b = null 	 	// 此对象的引用计数为 0(无引用)

用引用计数法会存在内存泄露,下面来看原因:

function test(){
    let A = new Object()
    let B = new Object()
    A.b = B
    B.a = A
}

对象 A 和 B 通过各自的属性相互引用着,按照上文的引用计数策略,它们的引用数量都是 2,但是,在函数 test 执行完成之后,对象 A 和 B 是要被清理的,但使用引用计数则不会被清理,因为它们的引用数量不会变成 0,假如此函数在程序中被多次调用,那么就会造成大量的内存不会被释放

缺点
引用计数的缺点想必大家也都很明朗了,首先它需要一个计数器,而此计数器需要占很大的位置,因为我们也不知道被引用数量的上限,还有就是无法解决循环引用无法回收的问题,这也是最严重的

JavaScript 对象生命周期的理解?

当创建一个对象时,JavaScript 会自动为该对象分配适当的内存垃圾回收器定期扫描对象,并计算引用了该对象的其他对象的数量如果被引用数量为 0,或惟一引用是循环的,那么该对象的内存即可回收

相关文章:

  • 面试官:去重和幂等的理解掌握多少?
  • 【毕业设计】大数据电商销售预测系统(数据分析)
  • 微信小程序生成海报工具Painter
  • wordpress网站搭建(centos stream 9)
  • 【SpringBoot】之浅谈 SpringBoot Starter
  • 数据挖掘——如何利用Python实现产品关联性分析apriori算法篇
  • Flutter 打包APK aab
  • [车联网安全自学篇] Android安全之检测APK中调试代码是否暴露敏感信息
  • 人生的镜像-菌群人生,从出生到死亡的菌群演替
  • 树莓派Remote GPIO启用方法
  • 安卓手机如何使用第三方主题,制作专属自己喜好的主题
  • 为什么拼多多总能给市场带来惊喜?
  • java计算机毕业设计甜趣网上蛋糕店订购系统源码+系统+数据库+lw文档+mybatis+运行部署
  • java计算机毕业设计铜仁学院毕业就业管理系统源码+系统+数据库+lw文档+mybatis+运行部署
  • 江川第一镰启动仪式 国稻种芯:北大荒2300余万亩水稻收获
  • Google 是如何开发 Web 框架的
  • -------------------- 第二讲-------- 第一节------在此给出链表的基本操作
  • Apache Zeppelin在Apache Trafodion上的可视化
  • css选择器
  • Debian下无root权限使用Python访问Oracle
  • es6(二):字符串的扩展
  • Eureka 2.0 开源流产,真的对你影响很大吗?
  • HTML中设置input等文本框为不可操作
  • Linux编程学习笔记 | Linux IO学习[1] - 文件IO
  • MyEclipse 8.0 GA 搭建 Struts2 + Spring2 + Hibernate3 (测试)
  • mysql 数据库四种事务隔离级别
  • Redux系列x:源码分析
  • Swoft 源码剖析 - 代码自动更新机制
  • Work@Alibaba 阿里巴巴的企业应用构建之路
  • 动手做个聊天室,前端工程师百无聊赖的人生
  • 对话:中国为什么有前途/ 写给中国的经济学
  • 仿天猫超市收藏抛物线动画工具库
  • 微服务框架lagom
  • 云大使推广中的常见热门问题
  • 运行时添加log4j2的appender
  • 怎么把视频里的音乐提取出来
  • 怎样选择前端框架
  • Hibernate主键生成策略及选择
  • 仓管云——企业云erp功能有哪些?
  • 如何在 Intellij IDEA 更高效地将应用部署到容器服务 Kubernetes ...
  • ​Java并发新构件之Exchanger
  • #NOIP 2014# day.1 生活大爆炸版 石头剪刀布
  • #常见电池型号介绍 常见电池尺寸是多少【详解】
  • $.ajax中的eval及dataType
  • (4)STL算法之比较
  • (delphi11最新学习资料) Object Pascal 学习笔记---第8章第2节(共同的基类)
  • (笔试题)分解质因式
  • (解决办法)ASP.NET导出Excel,打开时提示“您尝试打开文件'XXX.xls'的格式与文件扩展名指定文件不一致
  • (一)SpringBoot3---尚硅谷总结
  • (转载)OpenStack Hacker养成指南
  • (最简单,详细,直接上手)uniapp/vue中英文多语言切换
  • **Java有哪些悲观锁的实现_乐观锁、悲观锁、Redis分布式锁和Zookeeper分布式锁的实现以及流程原理...
  • .chm格式文件如何阅读
  • .NET 8.0 中有哪些新的变化?
  • .NET CF命令行调试器MDbg入门(一)