JavaScript 内存管理 & 垃圾回收机制

标记清除

js 中最常用的垃圾回收方式就是标记清除。当变量进入环境时,例如,在函数中声明一个变量,就将这个而变量标记为“进入环境”。从逻辑上讲,永远不能释放进入环境的变量所占用的内存,因为只要执行流进入相应的环境,就可能会用到它们。而当变量离开环境时,则将其标记为“离开环境”。

引用计数

这是最简单的垃圾收集算法。此算法把“对象是否不再需要”简化定义为“对象有没有其他对象引用它”。如果没有引用指向该对象(零引用),对象将被垃圾回收机制回收。
Netscape Navigator3 是最早使用引用计数策略的浏览器,但很快它就遇到了一个严重的问题:循环引用。循环引用指的是对象 A 中包含一个指向对象 B 的指针,而对象 B 中也包含一个指向对象 A 的引用。

1
2
3
4
5
6
7
function fn() {
var a = {};
var b = {};
a.pro = b;
b.pro = a;
}
fn();

以上代码a和b的引用次数都是2,fn()执行完毕后,两个对象都已经离开环境,在标记清除方式下是没有问题的,但是在引用计数策略下,因为a和b的引用次数不为0,所以不会被垃圾回收器回收内存,如果fn函数被大量调用,就会造成内存泄漏。在IE7与IE8上,内存直线上升。
最简单的方式就是自己手工解除循环引用,比如刚才的函数可以这样

1
2
myObject.element = null;
element.o = null;

内存管理

1、什么时候触发垃圾回收?
垃圾回收周期性运行,如果分配的内存非常多,那么回收工作也会很艰巨,确定垃圾回收时间间隔就变成了一个值得思考的问题。IE6 的垃圾回收是根据内存分配量运行的,当环境中存在 256 个变量、4096 个对象、64K 的字符串任意一种情况的时候就会触发垃圾回收器工作,看起来很科学,不用按一段时间就调用一次,有时候会没必要,这样按需调用不是很好嘛?但是如果环境中就是有这么多变量一直存在,现在脚本如此复杂,很正常,那么结果就是垃圾回收器一直在工作,这样浏览器就没法玩了。

微软在 IE7 中做了调整,触发条件不再是固定的,而是动态修改的,初始值和IE6相同,如果垃圾回收器回收的内存分配量低于程序占用内存的 15%,说明大部分内存不可被回收,设的垃圾回收触发条件过于敏感,这时候把临界条件翻倍,如果回收的内存高于 85%,说明大部分内存早就该清理了,这时候把触发条件置回。这样就使垃圾回收工作智能了很多。

2、合理的 GC 方案
1)、JavaScript 引擎基础 GC 方案是(simple GC):mark and sweep(标记清除),即:

  • 遍历所有可访问的对象。
  • 回收已不可访问的对象。

2)、GC 的缺陷
和其他语言一样,JavaScript 的 GC 策略也无法避免一个问题:GC 时,停止响应其他操作,这是为了安全考虑。而 JavaScript 的 GC 在 100ms 甚至以上,对一般的应用还好,但对于 JS 游戏,动画连贯性要求比较高的应用,就麻烦了。这就是新引擎需要优化的点:避免 GC 造成的长时间停止响应。

总结

一般不用 setInterval,而用 setTimeout 的延时递归来代替 interval。
setInterval 会产生回调堆积,特别是时间很短的时候。

扩展

setInterval 有个很烦的地方就是当 js 主程序空闲的时候,执行代码队列里面的代码的时候,如果此时候我们有一个问题,定时器是等到回调执行完,才开始计时进行下次循环呢?还是只要一次计时完毕,插入回调之后不管回调执不执行就开始计时呢?答案显示是后者,这也就是我说 setInterval 坑的原因啊,因为这会出现一种情况,当我们插入回调的时候前队列有别的代码在执行,这时候回调肯定是不会执行的,因此如果这个时候无限定时时间到了会再次插入回调,这个时候如果发现队列中的第一次回调没有执行,那么再次插入的回调浏览器就默认取消,(这是以防出现回调连续执行多次的情况)但是这又引发了新的情况就是有些回调是不能取消掉的?

转载于:https://www.cnblogs.com/bonelee/p/8134748.html

JS垃圾回收——和其他语言一样,JavaScript 的 GC 策略也无法避免一个问题:GC 时,停止响应其他操作,这是为了安全考虑...相关推荐

  1. 前端面试常考题:JS垃圾回收机制

    摘要:众所周知,应用程序在运行过程中需要占用一定的内存空间,且在运行过后就必须将不再用到的内存释放掉,否则就会出现下图中内存的占用持续升高的情况,一方面会影响程序的运行速度,另一方面严重的话则会导致整 ...

  2. js垃圾回收的标记清理与引用计数

    js是使用垃圾回收的语言,也就是说执行环境负责在代码执行时管理内存.js为开发者卸下跟踪内存这个负担,通过自动内存管理实现内存分配和闲置资源回收.基本思路很简单:确定哪个变量不会再使用,然后释放它所占 ...

  3. JS 垃圾回收机制解析

    概述 JS是一门具有自动垃圾回收机制的语言,开发人员不必关心内存分配和回收问题. JS的垃圾回收机制是为了以防内存泄漏,内存泄漏的含义就是当已经不需要某块内存时这块内存还存在着,垃圾回收机制就是间歇的 ...

  4. js垃圾回收机制,内存泄露和内存溢出,解决闭包产生的内存泄露详解

    一.内存的周期和回收机制 分配内存----->使用内存----->释放内存 1.JS 环境中分配的内存有如下声明周期: 内存分配:当我们声明变量.函数.对象的时候,系统会自动为他们分配内存 ...

  5. js垃圾回收机制(Gc)

    js垃圾收机制(Gc) 1.GC(garbage collection):js具有自动垃圾回收机制,即执行环境会负责管理代码执行过程中使用的内存, 2.GC会定期(周期性)找出那些不再继续使用的变量, ...

  6. JS垃圾回收机制是怎样的?

    1.概述 js的垃圾回收机制是为了防止内存泄漏(已经不需要的某一块内存还一直存在着),垃圾回收机制就是不停歇的寻找这些不再使用的变量,并且释放掉它所指向的内存. 在JS中,JS的执行环境会负责管理代码 ...

  7. JavaScript进阶(十五):JS 垃圾回收机制

    文章目录 一.前言 二.JavaScript 中的内存管理 三.全停顿(Stop The World ) 3.1 JavaScript 中的垃圾回收 3.1.1 引用计数 3.1.2 标记清除(Mar ...

  8. 从闭包函数的变量自增的角度 - 解析js垃圾回收机制

    GitHub 前言 感觉每一道都可以深入研究下去,单独写一篇文章,包括不限于闭包,原型链,从url输入到页面展示过程,页面优化,react和vue的价值等等. 代码实现 const times = ( ...

  9. js垃圾回收机制和引起内存泄漏的操作

    Js具有自动垃圾回收机制.垃圾收集器会按照固定的时间间隔周期性的执行. JS中最常见的垃圾回收方式是标记清除. 工作原理:是当变量进入环境时,将这个变量标记为"进入环境".当变量离 ...

最新文章

  1. PDD面试题:new一个对象的过程中发生了什么?
  2. RIA Service 的 SOAP EndPoint
  3. Leetcode 200 岛屿数量 (每日一题 20210720)
  4. kdbchk: the amount of space used is not equal to block size
  5. oauth2 java 获取token_OAuth2 Token 一定要放在请求头中吗?
  6. Python中计算文件的MD5值
  7. luogu2680 运输计划
  8. C++读取Access数据库
  9. 单片机c语言轻松入门 完整版,单片机C语言轻松入门
  10. 安卓手机有坏点测试软件,手机屏幕坏点怎么检测
  11. CFD软件如何选择?STAR CCM+ VS ANSYS Fluent
  12. SpringBoot+MyBatisPlus+Vue+ElementUI实现前后端分离的物业管理系统
  13. 伤害世界稳定服务器,伤害世界哪个服务器好_伤害世界怎么选服务器_牛游戏网...
  14. java print 格式化输出_java 格式化输出方法
  15. BUU刷题记录——5
  16. 《Adobe Illustrator CS5中文版经典教程》—第0课0.15节创建和编辑渐变
  17. left join on多条件深度理解
  18. php代码转换工具,推荐几款格式化工具以及代码转换工具
  19. 快速排序和归并排序中一趟的理解(递归和非递归)
  20. web系统开发中关于企业里各种系统分类

热门文章

  1. Markdown编辑表格时如何输入竖线('|', pipe,vertical bar)
  2. matlab绘制bland-altman,制作Bland-Altman图的步骤和程序(以SPSS作图为例讲解)
  3. php curl异步跳转,php curl批处理--可控并发异步
  4. discuz登陆首页后提示style_1_commen.css,关于Discuz用户面板必须刷新才能显示登录状态的问题解决办法...
  5. matlab混合编程设置,matlab c++ 混合编程初始设置
  6. cmd做个定时弹窗_揭秘200元山寨苹果耳机!一颗耳边的“定时炸弹”...
  7. java请求怎么获取token,如何获取变量token的值
  8. linux mysql5.7.11安装_centos 7 安装mysql 5.7.11
  9. linux mentohust dhcp,MentoHUST的使用教程详解
  10. Java比较同一map是否相同_Java 中HashTable、HashMap、TreeMap三者区别,以及自定义对象是否相同比较,自定义排序等...