手机版

vue单页应用程序内存泄漏定位和修复总结

时间:2021-08-21 来源:互联网 编辑:宝哥软件园 浏览:

在前端项目(电脑端)中,定位内存泄漏通常比修复内存泄漏更困难。即使谷歌浏览器提供了Memory工具,面对成千上万的元素和复杂的引用关系,仍然很难快速定位问题代码块。

1.什么是内存泄漏?

系统进程不再使用的内存没有及时释放,称为内存泄漏。当内存占用越来越高时,不仅会影响系统性能,还会导致进程崩溃。Chrome限制了浏览器可以使用的内存限制(64位为1.4GB,32位为1.0GB),这意味着浏览器不能直接操作一些大内存对象。

执行垃圾收集时,V8引擎会阻塞JavaScript应用程序逻辑,然后重新执行JavaScript应用程序逻辑,直到垃圾收集完成,这称为“停止世界”。如果V8的堆内存是1.5GB,那么V8做一个小的垃圾回收需要50ms以上,导致假死。

二、JS内存管理和垃圾收集机制GC

高级语言基本上都有垃圾收集来自动管理内存,减轻了程序员的负担,解决了内存泄漏的问题。但是不允许手动触发,在内存管理上也不能干预。

旧浏览器使用引用计数来管理内存,即每个引用增加一个,释放时减少一个。当该值的引用数变为0时,可以回收其内存空间。缺点是循环引用时无法回收。

现代浏览器基本上都是用Mark-and-Sweep来管理内存的,也就是浏览器周期性的从某个根元素(比如window对象)开始寻找引用变量以及这些变量引用的变量,并且一直找下去。可以找到的变量是可用的,找不到的变量会被内存回收。

缺点是内存清空后会有很多详细的块,所以导出了标记-排序的方法,这里就不详细解释了。

第三,有几种情况下,内存泄漏容易发生在VUE

内存泄漏是一个累积的过程,只有当页面生命周期稍长时,问题才会暴露出来。频繁的交互会加快累积过程,在部分显示页面上很难暴露这样的问题。所以很多时候,我们都是被动地等待问题暴露出来,然后再进行调查。主动分析通常很困难。Vue页面多为单页应用,交互度高,停留时间长。本文主要研究自由dom对象,还有时间补充常见的JS变量。

1.全局变量导致的内存泄漏

Template div id='home '这里是主页/div/templatescriptexportdefault { mounted(){ window . test={//这里,这个页面的dom对象名为: 'home '在全局window对象中被引用。节点:文档。getelementbyid(' home ')} }/script按Heap snapshots键,搜索distributed,发现文档树中没有分离的dom元素,这是正常现象。

更改跳转到其他页面的路线,按堆快照键,搜索分离,发现有两个dom元素浮动在当前页面之外。显然,窗口对象引用了主页中的div。即使此时主页已经被破坏,但是home中的dom元素仍然驻留在内存中,不能被释放。

解决方法是在卸载页面时处理引用。

Template div id='home '这里是主页/div/templatescriptexportdefault { mounted(){ window . test={//这里,这个页面的dom对象名为: 'home '在全局window对象中被引用。节点:文档。getelementbyid ('home')}},销毁(){window。测试=null//卸载页面时未引用}}/script2。除了直接引用之外,window的本机方法还具有引用dom元素的效果,因此它们不能被释放。

Template div id='home '这里是主页/div/templatescriptexportdefault { mounted(){ window . addevent listener(' resize ',this . func)//window对象引用了主页的方法}。方法: {func () {console.log('这是主页的一个功能')} }/script

同样的解决方案是在页面被破坏时取消引用并释放内存

已安装(){窗口。addeventlistener ('resize '),这。func)},beforedestroy () {window。removeeventlistener ('resize '),这。func)} 3。一些全局方法使用不当也会导致内存无法释放,卸载页面时也可以考虑取消引用。

模板div id='home '这是主页/div/templatescriptexportdefault { mounted(){ this。事件总线。$ on ('hometask ',RES=this。func (RES))},methods : { func(RES){ console . log(RES)} } }/script

已安装(){此。事件总线。$ on ('hometask ',res=this。func (res))},销毁(){this。事件总线。$ off ()}创建free dom节点的原因有很多,不仅仅是这三个。总而言之:

1.销毁页面上的节点绑定到1.window对象、事件总线和全局vuex,节点不会随页面一起销毁。

2.使用第三方库创建一个实例,该实例一般提供销毁函数,页面跳转时不调用正确的销毁函数

3.有些学生会说,在页面中使用闭包也会导致内存泄漏。vue框架中有一种管理内存的机制。只要写对了,理论上不会造成内存泄漏

摘要

以上是边肖介绍的vue单页应用内存泄漏定位和修复问题的总结。希望对大家有帮助。如果你有任何问题,请给我留言,边肖会及时回复你。非常感谢您对我们网站的支持!如果你觉得这篇文章对你有帮助,请转载,请注明出处,谢谢!

版权声明:vue单页应用程序内存泄漏定位和修复总结是由宝哥软件园云端程序自动收集整理而来。如果本文侵犯了你的权益,请联系本站底部QQ或者邮箱删除。