正文从这开始~

内存问题对于后端童鞋而言可能是家常便饭,特别是C++童鞋。我在实习时做过半年的c++游戏客户端开发(也是前端开发哦),也见识了各式各样的内存问题,就说说我的第一个坑,当时做个需求,就是在玩家名字上加些酷炫的封号(就是下图中红框中的图片),人小不懂事,频繁去new一个图像出来,却不去释放它,导致客户端跑个几个小时就会崩溃,虽然很快就被揪出来修复掉,却也留下了心理阴影(5年了,依然历历在目啊)。

话题回到前端开发,很幸运,js还是拥有比较完善的gc机制,使得我们不需要时时刻刻像C++那样去关心内存问题。甚至说在传统网页开发中,极少需要去关注内存泄漏问题,因为即使有些许内存泄漏,页面刷新又将内存拉回起点。但随着SPA的流行,特别是移动app的火爆,js的内存问题也许会成为体验的瓶颈。

什么是内存泄漏

来自wikipedia的解释:“由于疏忽或错误造成程序未能释放已经不再使用的内存”。其实在有gc的高级语言中,我们可以定义得更仔细一点:“当我们不再使用某块内存的时候,却不让gc去回收它“。

js的内存管理机制以及一些常见的js内存泄漏点,本文就不一一介绍了,网上上已经有不少好的文章将这些点讲的很清楚。有兴趣的可以自行搜索。

什么样的内存泄漏是致命的

我写了一个内存泄漏的公式:

(n: 总共n个内存泄漏的地方;m:单个内存泄漏点所占用的内存;f:单个内存泄漏点的频次)

web前端的内存泄漏不像server端,server端哪怕一个极小的内存泄漏,都会因为海量的请求被放大(f极大),内存泄漏对于server端来说是致命的。但对于web前端来说,大部分的操作都很低频,也就是说很多时候,即使有内存泄漏,但是在整个页面生命周期里面,内存泄漏只是也只是增长了很少一部分,对用户体验很难造成影响。那么什么样的情况会导致致命issue?

我们来分析下上面公式中中的三个因子(很明显三个因子都对结果都是正相关关系):

1. m(单次内存泄漏的内存量)

无论是前端还是后端,想要单次泄漏较大量的内存还是不容易的,即使有这样的情况发生,想要找出根源也相对比较容易的,这种情况请开发不要作死。

2. f (单个内存泄漏频次)

我在km上搜到的前端js(不包含node)内存实战记录,zone miniportal 内存泄漏分析和经过和MiniPortal JS内存泄漏定位二(内部文章),虽然是09年的事情了,但我认为还是非常有代表性的。论大小pv上报返回的image对象,ajax获取的xml文件这能有多大?2k?但是在长时间打开的qzone页面上被一次又一次的执行,终成影响体验的大问题。

我也粗略总结下前端的一些高频操作(欢迎补充):

  • 强交互应用中的ajax或者socket请求处理

  • setInterval, requestAnimationFrame等循环处理

  • click等高频处理函数

我处理过的内存泄漏问题中,bc的情况其实是很少的,主要致命的内存泄漏出现在a情况,因为大部分请求都可能伴随着页面的局部刷新,特别是引入第三方框架时(比如chart相关,highchart、d3等),仅仅remove相应dom一般不会释放第三方对象,这时候就需要手动进行destroy。

例:用vue包装的highchart组件需要在组件生命周期末端进行销毁

反例:某知名报表系统, 页面如下:

点击刷新后监控内存变化,下图中四组内存快照分别是初始,请求20次,请求40次,请求60次时的内存情况(有兴趣的可以用timeline进行实验)。因为每次刷新的数据是一致的,将snap4雨snap3进行比较,按照大小进行分类会看到有不少每20个一组的内存块,再查看它的gc路径,泄漏点就显而易见了,真的是chart先动手的。

想象一下你的移动webapp在刷页面是刷占了300M的内存。。。。。。。。

3. n(总共n个内存泄漏的地方)

在传统网页中,单个页面中的内存泄漏点还是屈指可数的,但是在SPA中,页面的跳转并没有刷新,上个页面的内存泄漏点很有可能也不会被释放,这就会导致内存会一直递增,在某个阶段爆发,这正是SPA所面临的内存挑战。

举个非常普遍的例子Popup,因为点击其他区域时,需要隐藏弹出框,我们会在document上绑定click事件来处理隐藏的逻辑,如果在组件被销毁时,没有去解绑该事件的话,就导致了该处理函数中的引用无法被释放,在这个例子中这个popup对象都不会被释放。现在最流行的vue组件库element ui就存在这样的问题,谁有空可以去提个issue。

正面例子:在生命周期末期记得unbind

最后,今天的文章长度会适中吗?可能你还需要了解看看以下为你推荐的文章:

【第591期】4类 JavaScript 内存泄露及如何避免

【第528期】了解 JavaScript 应用程序中的内存泄漏

转---单页面应用下的JS内存管理的更多相关文章

  1. 闭包 与 js内存管理

    参考:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Memory_Management            https://blog ...

  2. vue单页面条件下添加类似浏览器的标签页切换功能

    在用vue开发的时候,单页面应用程序,而又有标签页这种需求,各种方式实现不了, 从这个 到这个,然后再返回上面那个 因为每个标签页的route不一样,导致组件重新渲染的问题,怎么都不知道如何实现... ...

  3. iOS 下ARC的内存管理机制

    本文来源于我个人的ARC学习笔记,旨在通过简明扼要的方式总结出iOS开发中ARC(Automatic Reference Counting,自动引用计数)内存管理技术的要点,所以不会涉及全部细节.这篇 ...

  4. angular ,require.js, angular-async-loader实现单页面路由,控制器js文件分离

    https://github.com/heboliufengjie/appRoute/tree/re re 分支,实现,路由配置,控制器js文件分离

  5. 单页面应用下刷新当前iframe

    $('button.layui-btn-elastic-2').click(function(){ var srcIframe=$(".layui-side ul li dd"). ...

  6. Windows平台下主要的内存管理途径

    new / delete   malloc / free    CoTaskMemAlloc / CoTaskMemFree    IMalloc::alloc / IMalloc/free    G ...

  7. JS内存管理

    背景: 分配给Web浏览器的内存通常比分配给电脑桌面的内存少,因为担心运行JS的网页耗尽全部系统内存而导致系统崩溃 内存限制问题不仅影响给变量分配内存,还会影响调用栈以及在一个线程中能够同时执行的语句 ...

  8. JS内存管理与垃圾回收

    内存分配 var n = 374; // 为数字分配内存 var s = 'sessionstack'; // 为字符串分配内存 var o = { a: 1, b: null }; // 为对象及其 ...

  9. JS内存管理测试

    打开调试器,切换到timer,点击左下角的record按钮开始,切换到memory视图,在文档中点击鼠标左右键,看股价走势图 function Allocate(kbs){ this.mem = ne ...

随机推荐

  1. zend studio导入外部项目乱码怎么解决

    在zendstudio ide中,导入一个工程后,发现工程里面很多的文件都打上了红色的叉叉,打开这些文件一看,发现只要是有汉字存在的文件,都出现了乱码.按住alt+enter发现,该文件的编码默认为g ...

  2. 2018.01.04 bzoj5291: [Bjoi2018]链上二次求和(线段树)

    传送门 线段树基础题. 题意:给出一个序列,要求支持区间加,查询序列中所有满足区间长度在[L,R][L,R][L,R]之间的区间的权值之和(区间的权值即区间内所有数的和). 想题555分钟,写题202 ...

  3. 2018.10.24 bzoj3195: [Jxoi2012]奇怪的道路(状压dp)

    传送门 f[i][j][k]f[i][j][k]f[i][j][k]表示前iii个点连了jjj条边,第i−K+1i-K+1i−K+1~iii个点连边数的奇偶性为kkk时的方案数. 转移规定只能从后向前 ...

  4. Windows上使用Git管理文件

    今天在搜索ffmpeg相关资料时,需要通过.sh脚本文件下载git上的代码文件,最后通过在Windows上安装了git,并在git.bash中执行bash ffmpeg.sh解决了代码下载问题,顺便学 ...

  5. mysql学习之路_sql

    查看数据库: Show databases; 查看指定部分数据库:模糊查询 Show databases like ‘patten’;--paatten是匹配模式 %:表示是匹配模式 _:表示匹配单个 ...

  6. Hadoop Hbase理论及实操

    Hbase特点 HBase是一个构建在HDFS上的分布式列存储系统:HBase是基于Google BigTable模型开发的,典型的key/value系统:HBase是Apache Hadoop生态系 ...

  7. DDR4 PSOD输出的优点--DBI的优点

    DDR4是JEDEC组织关于DRAM器件的下一代标准.DDR4主要是针对需要高带宽低功耗的场合.这些需求导致了DDR4芯片引入了一些新的特点,这些新的特点,导致在系统设计中,引入一些新的设计需求. D ...

  8. js中的事件代理(委托)

    1,什么是事件委托:通俗的讲,事件就是onclick,onmouseover,onmouseout,等就是事件,委托呢,就是让别人来做,这个事件本来是加在某些元素上的,然而你却加到别人身上来做,完成这 ...

  9. redis-server进程CPU百分百问题

    结论:待确认是否为redis的BUG,原因是进程实际占用的内存远小于配置的最大内存,所以不会是内存不够需要淘汰.CPU百分百redis-server进程集群状态:slave临时解决办法:使用gdb将d ...

  10. js基础学习笔记(一)

    * 在js编写过程中,尽量保持统一使用单引号 'XXXX': * 所有变量都要声明 var,避免全局函数调用的冲突: 1.1    输出内容 docment.write(‘aileLi’); 改变某I ...