转---单页面应用下的JS内存管理
正文从这开始~
内存问题对于后端童鞋而言可能是家常便饭,特别是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内存管理的更多相关文章
- 闭包 与 js内存管理
参考:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Memory_Management https://blog ...
- vue单页面条件下添加类似浏览器的标签页切换功能
在用vue开发的时候,单页面应用程序,而又有标签页这种需求,各种方式实现不了, 从这个 到这个,然后再返回上面那个 因为每个标签页的route不一样,导致组件重新渲染的问题,怎么都不知道如何实现... ...
- iOS 下ARC的内存管理机制
本文来源于我个人的ARC学习笔记,旨在通过简明扼要的方式总结出iOS开发中ARC(Automatic Reference Counting,自动引用计数)内存管理技术的要点,所以不会涉及全部细节.这篇 ...
- angular ,require.js, angular-async-loader实现单页面路由,控制器js文件分离
https://github.com/heboliufengjie/appRoute/tree/re re 分支,实现,路由配置,控制器js文件分离
- 单页面应用下刷新当前iframe
$('button.layui-btn-elastic-2').click(function(){ var srcIframe=$(".layui-side ul li dd"). ...
- Windows平台下主要的内存管理途径
new / delete malloc / free CoTaskMemAlloc / CoTaskMemFree IMalloc::alloc / IMalloc/free G ...
- JS内存管理
背景: 分配给Web浏览器的内存通常比分配给电脑桌面的内存少,因为担心运行JS的网页耗尽全部系统内存而导致系统崩溃 内存限制问题不仅影响给变量分配内存,还会影响调用栈以及在一个线程中能够同时执行的语句 ...
- JS内存管理与垃圾回收
内存分配 var n = 374; // 为数字分配内存 var s = 'sessionstack'; // 为字符串分配内存 var o = { a: 1, b: null }; // 为对象及其 ...
- JS内存管理测试
打开调试器,切换到timer,点击左下角的record按钮开始,切换到memory视图,在文档中点击鼠标左右键,看股价走势图 function Allocate(kbs){ this.mem = ne ...
随机推荐
- 区间DP初探 P1880 [NOI1995]石子合并
https://www.luogu.org/problemnew/show/P1880 区间dp,顾名思义,是以区间为阶段的一种线性dp的拓展 状态常定义为$f[i][j]$,表示区间[i,j]的某种 ...
- css中的属性
一.字体 1.字体类型 font-family "Microsoft YaHei","微软雅黑" 2.字体大小 font-size 默认16px 3.字体字重 ...
- django之http
一 http协议介绍 http协议(Hyper Text Transfer Protocol):超文本传输协议,是基于应用层的面向对象协议,靠tcp协议和IP来传输数据,请求和响应是http协议的基本 ...
- Python开课复习9-28
一.什么是迭代器#迭代器即迭代的工具,那什么是迭代呢?#迭代是一个重复的过程,每次重复即一次迭代,并且每次迭代的结果都是下一次迭代的初始值 举例: l=[1,2,3] count=0 while co ...
- C++STL 预定义函数对象和函数适配器
预定义函数对象和函数适配器 预定义函数对象基本概念:标准模板库STL提前定义了很多预定义函数对象,#include <functional> 必须包含. 1使用预定义函数对象: void ...
- Json跨域请求数-Jquery Ajax请求
同步请求,async(是否异步) //同步请求,等待并接收返回的结果 var result = $.ajax({ type: "GET", url: address, async: ...
- Java网络技术-待续
TCP Sockets基础 Sockets,是用户程序与TCP/IP协议的中介. 实现TCP Sockets通信,需要本地IP和端口,对方IP和端口.客户端发通信请求,发送或接收流,关 ...
- HTML5表单新属性
HTML5表单新属性 autofocus 自动聚焦 <input type="text" autofocus> placeholder占位文本 tel ...
- uva1653
本来想刷道签到题结果被卡住了.这题题意描述有点问题,数字又不一定都是个位数...难道是我英语太差了? digits就表示0~9这几个数?唉,还是太弱了.这题就是用了一个bfs,应该说还是有点意思的,直 ...
- POJ3280--Cheapest Palindrome(动态规划)
Keeping track of all the cows can be a tricky task so Farmer John has installed a system to automate ...