-
Notifications
You must be signed in to change notification settings - Fork 39
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
前端内存泄露浅析 #158
Comments
内存泄露分析Snapshot相关知识点JS heap sizewindow.performance.memory对象的属性。 jsHeapSizeLimit: 2197815296
totalJSHeapSize: 12068848
usedJSHeapSize: 10730032 totalJSHeapSize和usedJSHeapSize的区别是什么? 通过以下代码,可以观察当前document的usedJSHeapSize占用状况,从而分析是否存在内存泄露性能问题。 setInterval(()=>{
console.log(performance.memory);
},2000) 通过观察可以发现,js占用内存(不包括空闲内存)在一直升高,停留一段时间以后也GC不到页面初始化的的大小。 也可以在Chrome的任务管理器中,开启JavaScript使用的内存的监控。但是这样会开启看到所有tab甚至是插件的内存占用信息,不如code的方式直观和geek。 Heap snapshot堆快照。其实就是当前页面的js对象及其相关的DOM节点的内存分布情况。
可以在内存泄露前生成一份堆快照,再在内存泄露后生成一份堆快照。通过对比的方式,找出两份堆快照存在的内存泄露点。最好是在一次操作后分析,以便分析出问题。 Shallow SizeShallow Size 是对象本身hold的内存。
参考资料:即使是一个小对象,都可能间接的hold了庞大的内存。从而导致自动GC程序不能处理掉这些被间接hold的内存。 Retained Size这是删除了对象及其依赖对象后,可以释放的内存大小,这些依赖从GC root是无法访问到的。 官方解释很拗口,简单理解其实就是对象及其依赖对象的内存大小。 Comparison中的分析字段
Heap Snapshot中的Constructor
一个构造函数的属性
Shallow size、Retained size、Freed size、Delta size的size是以什么为单位?所有的size都是以字节为单位的。
|
内存泄露分析Snapshot的疑惑和实践为什么一次菜单切换会导致6MB的内存泄露?素材列表->产品列表->素材列表,增加了6MB的内存占用。 刚好VueComponent也从377个(10%)增大到600个(22%),也是从增大了12%。 所以初步断定,是由于VueComponent没有GC导致的。 第一组疑问(理论):
以上信息是在Summary中展示的,那么如何对比两次快照呢? 第二组疑问(实践):
|
Chrome DevTools Elements的Event Listeners分析内存泄露vue中的全局事件销毁,避免listener内存泄露。 DOM0级事件销毁 window.onbeforeunload = () => {};
window.onbeforeunload = null; // 销毁,可以在vue的destroyed生命周期(最好在这个,因为无需在beforeDestroy引用vue实例)或beforeDestroy。 DOM2级事件销毁 this.foo= (e) => {}
window.addEventListener('resize', this.foo);
window.removeEventListener('resize', this.foo);// 销毁,可以在vue的beforeDestroy生命周期(引用vue实例最好在这个周期销毁)或destroyed。 通过观察可以发现,一次菜单切换,减少了一个冗余的全局事件监听器,性能有些许提升。 |
总结与思考经过一系列分析我们发现,可以通过以下几种方式分析内存泄露的问题并修复。
前端同学在选型前端UI框架时,不妨先测试测试是否存在内存泄露。 参考资料:
|
手上负责的vue项目最近出现一个这样的问题,用户用着用着就出现:”喔唷,崩溃啦!“的提示。
做了以下性能优化尝试:
主动销毁对象及其子对象
vue-cropper.js,组件实例不会主动销毁,需要主动调用destroy方法销毁。
createjs/easeljs,组件实例需要手动销毁canvas画布,
maker.stage.canvas = null;maker.stage.removeAllChildren();
主动取消监听listener
createjs/easeljs,
maker.stage._eventListeners = null;maker.stage.removeAllEventListeners();
。本地搜索减少组件DOM渲染
iview的select组件,当数据量过大时,DOM渲染会占用很大的内存,非常吃性能。因此为其增加了渲染指定个数的功能,例如首次渲染只渲染20个,之后的搜索从已经加载好的数据中搜索并渲染。
有一定的收效,但是在仍然存在性能问题,切换菜单的过程中,Memory中的Javascript VM instance以100MB/次的速度增加,而且还是在没有数据的情况下。
因此,迫切的需要一次深度的性能优化,以解决当前项目遇到的问题。
解决完这个问题我将增强技能:
我将记录以下深度分析内存泄露的相关内容:
The text was updated successfully, but these errors were encountered: