博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
JS的内存机制以及垃圾回收机制
阅读量:6051 次
发布时间:2019-06-20

本文共 1358 字,大约阅读时间需要 4 分钟。

JS内存空间分为栈、堆、池(一般归并到栈中)

基本数据类型string、number、boolean、null、undefined保存在栈中

复杂数据类型object保存在堆中

常量存放在池中

js中分配的内存的生命周期为:

内存分配->内存使用->内存回收

 

垃圾回收机制

js具有自动回收机制,垃圾收集器会按照固定的时间间隔周期性的执行。

两种方式:

(1)标记清除

 原理:当变量进入环境时,将这个变量定义为“进入环境”,将变量离开环境时,将其标记为“离开环境”,标记“离开环境”的就回收内存。

 工作流程:

  • 垃圾回收器。在运行的时候给存储在内存中的所有变量都加上标记。
  • 去掉环境中的变量以及被环境中的变量引用的变量(闭包)的标记。
  • 此时仍有标记的变量视为即将要删除的变量
  • 垃圾回收器完成内存清除的工作,销毁那些带标记的值并回收他们所占的内存空间。

(2)引用计数

工作原理:跟踪记录每个值被引用的次数

工作流程:

  • 声明一个变量并将一个引用类型值赋值给这个变量,这个引用类型值的引用次数就是1
  • 同一个引用类型值又被赋值给另一个变量,这个引用类型值的引用次数就加1
  • 当包含这个引用类型值的变量又取得了另一个值,这个引用类型值的引用次数就会减1
  • 当引用次数变为0时,说明没法访问这个值了。
  • 当垃圾回收器下一次运行时就会释放引用次数为0的值所占的内存空间。

引用计数的问题:循环引用 。循环引用指的是对象A中包含一个指向对象B的指针,而对象B中也包含一个指向对象A的引用。请看下面这个例子

function problem(){         var objectA = new Object();    var objectB = new Object();      objectA.someOtherObject = objectB;    objectB.anotherObject = objectA; }

在这个例子中,objectA 和 objectB 通过各自的属性相互引用;也就是说,这两个对象的引用次数都是 2。

  在采用标记清除策略的实现中,由于函数执行之后,这两个对象都离开了作用域,因此这种相互引用不是个问题。但在采用引用计数策略的实现中,当函数执行完毕后,objectA 和 objectB 还将继续存在,因为它们的引用次数永远不会是 0。

 

哪些操作会造成内存泄漏?

内存泄漏指任何对象在不再拥有或不需要它之后依然存在,即这部分内存用完之后并没有返回到内存池。

 

(1)setTimeout第一个参数是字符串而不是函数的时候就会造成内存泄漏

(2)闭包

(3)控制台日志

(4)循环(两个对象彼此引用且彼此保留)

(5)全局变量

   如果你不断的创建全局变量,不管有没有用到他们,他们都将滞留在程序的整个执行过程中。

(6)事件监听器

  在页面中创建事件监听器,但是在页面跳转时,又忘记移除这些监听器,那么也可能导致内存泄漏。 

 

变量回收规则:

(1)全局变量不会被回收

(2)局部变量会被回收,也就是函数一旦运行完,函数内部的变量就会被销毁

(3)只要被另一个作用域引用就不会被销毁

 

转载于:https://www.cnblogs.com/xiaoan0705/p/8663203.html

你可能感兴趣的文章
检测点1.1
查看>>
android--------阿里 AndFix 热修复
查看>>
control.add()
查看>>
Sublime text3中配置Github
查看>>
Asp.net,C# 加密解密字符串
查看>>
网页视频播放器插件源码
查看>>
2019-4-23 plan
查看>>
[编解码] 关于base64编码的原理及实现
查看>>
WinDbg配置和使用基础
查看>>
转:Object-Runtime的基本数据类型
查看>>
JMJS系统总结系列----Jquery分页扩展库(五)
查看>>
Excel技巧之——英文大小写转换(转)
查看>>
Google 翻译的妙用
查看>>
常用的集合
查看>>
Unity3D工程源码目录
查看>>
杀死进程命令
查看>>
cookie 和session 的区别详解
查看>>
Mongodb对集合(表)和数据的CRUD操作
查看>>
Target runtime Apache Tomcat is not defined.错误解决方法
查看>>
VC++ 监视文件(夹)
查看>>