资讯专栏INFORMATION COLUMN

vue单页应用的内存泄露定位和修复(一)

solocoder / 511人阅读

摘要:在前端项目端中,内存泄露的定位往往比修复更加困难,即使浏览器有提供工具,但是面对成千上万的元素和错综复杂的引用关系,开发则依然很难快速定位到问题代码块。

在前端项目(PC端)中,内存泄露的定位往往比修复更加困难,即使google浏览器有提供Memory工具,但是面对成千上万的元素和错综复杂的引用关系,开发则依然很难快速定位到问题代码块。

一、什么是内存泄漏?
系统进程不再用到的内存,没有及时释放,就叫做内存泄漏(memory leak)。当内存占用越来越高,轻则影响系统性能,重则导致进程崩溃。Chrome限制了浏览器所能使用的内存极限(64位为1.4GB,32位为1.0GB),这也就意味着浏览器将无法直接操作一些大内存对象。

V8引擎在执行垃圾回收时会阻塞 JavaScript应用逻辑,直到垃圾回收结束再重新执行JavaScript应用逻辑,这种行为被称为“全停顿”(stop-the-world)。 若V8的堆内存为1.5GB,V8做一次小的垃圾回收需要50ms以上,造成假死现象。

二、JS内存管理和垃圾回收机制GC
高级语言基本都有垃圾回收机制(garbage collection)自动管理内存,降低程序员的负担,以达到解决内存泄漏的目的,但是不允许人为手动触发,无法对内存管理进行任何干预。

老版本的浏览器使用引用计数法(Reference Counting)来管理内存,即每次引用加一,被释放时减一,当这个值的引用次数变成 0 时,就可以将其内存空间回收,缺点是循环引用时无法回收。

现代浏览器基本采用标记清除法(Mark-and-Sweep)来管理内存,即浏览器周期性地从某个根元素(譬如 window 对象)开始找引用变量,及这些变量引用的变量,这样一直找下去。能找到的变量为可获得变量,不能找到的将被内存回收。

缺点是清除后内存会产生很多细化的分块,所以又衍生了标记-整理法,不细讲。

三、VUE中容易出现内存泄露的几种情况
内存泄露是一个累积的过程,只有页面生命周期略长的时候才暴露出问题,频繁交互能够加快累积的过程,偏展示的页面很难把这样的问题暴露出来(所谓刷新一下又能满血复活)。所以很多时候我们都是被动式的等待问题暴露然后进行排查的,主动式的分析通常比较难。vue页面大多是单页应用,高交互且停留时间久,处理不好很容易出现内存泄漏。本文章主要针对游离的dom对象进行排查,普通的JS变量排查有时间再补充。

1.全局变量造成的内存泄露



按下Heap snapshots键,搜索Detached,发现没有脱离文档树的dom元素,属于正常现象

改变路由跳转到other页面,按下Heap snapshots键,搜索Detached,发现有两处dom元素游离于当前页面之外,很明显是window对象引用了home页面中的div,即使此时home页面已经销毁,home中的dom元素却还驻留在内存中无法释放。

解决方案就是在页面卸载的时候顺便处理掉该引用。



2.除了直接引用,window的原生方法也会起到引用dom元素使其无法释放的效果。



解决方法一样,也是在页面销毁的时候,顺便解除引用,释放内存

mounted () {
    window.addEventListener("resize", this.func)
},
beforeDestroy () {
    window.removeEventListener("resize", this.func)
}

3.一些全局的方法使用不当也会造成内存无法释放,在页面卸载的时候也可以考虑解除引用



mounted () {
  this.$EventBus.$on("homeTask", res => this.func(res))
},
destroyed () {
  this.$EventBus.$off()
}

造成游离dom节点的原因还有很多,不止这三种,总结起来:
1.window对象、事件总线、全局vuex上绑定了已销毁页面上的节点,到时节点不随页面一起销毁
2.使用第三方库创建实例,第三方库一般会提供销毁函数,页面跳转时没有调用正确的销毁函数
3.有同学会说在页面中使用闭包也会造成内存泄露,在vue框架里有管理内存的机制,只要按照它的正确编写方法,理论上是不会造成内存泄露的

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/106302.html

相关文章

  • vue单页应用内存泄露定位修复

    摘要:在前端项目端中,内存泄露的定位往往比修复更加困难,即使浏览器有提供工具,但是面对成千上万的元素和错综复杂的引用关系,开发则依然很难快速定位到问题代码块。 在前端项目(PC端)中,内存泄露的定位往往比修复更加困难,即使google浏览器有提供Memory工具,但是面对成千上万的元素和错综复杂的引用关系,开发则依然很难快速定位到问题代码块。 一、什么是内存泄漏?系统进程不再用到的内存,没有...

    suxier 评论0 收藏0
  • vue单页应用内存泄露定位修复

    摘要:在前端项目端中,内存泄露的定位往往比修复更加困难,即使浏览器有提供工具,但是面对成千上万的元素和错综复杂的引用关系,开发则依然很难快速定位到问题代码块。 在前端项目(PC端)中,内存泄露的定位往往比修复更加困难,即使google浏览器有提供Memory工具,但是面对成千上万的元素和错综复杂的引用关系,开发则依然很难快速定位到问题代码块。 一、什么是内存泄漏?系统进程不再用到的内存,没有...

    maxmin 评论0 收藏0
  • [使用 Weex Vue 开发原生应用] 6 使用 vue-router

    摘要:使用值来作路由。原生应用本身就是多页的场景,页面间状态的隔离比共享更重要一些。使用开发的是原生应用,页面栈的管理使用的也是原生的特性,没有但是有模块可以实现页面的前进和后退等操作。 系列文章的目录在 ? 这里 (由于 我比较懒 最近一段时间在忙其他事,系列文章拖了好久终于又更新了。。。) 什么是 vue-router ? vue-router 官方文档 vue-router 是针对 V...

    leonardofed 评论0 收藏0
  • 查找并修复Android中内存泄露—OutOfMemoryError

    摘要:程序中很容易出现内存泄露问题。通常,内存泄露都与已泄露的活动相关。这是内存泄露的首要标志。将引用存储至某个或内部会导致内存泄露。查找并修复中的内存泄露技术分享第张根据类名在内存分析器中过滤对象现在,我们看到存在个实例。 【编者按】本文作者为来自南非约翰内斯堡的女程序员 Rebecca Franks,Rebecca 热衷于安卓开发,拥有4年安卓应用开发经验。有点完美主义者,喜爱美食。 本...

    MAX_zuo 评论0 收藏0
  • [译文]在iOS上自动检测内存泄露

    摘要:追踪内存泄露的根源。为此,在我们的开发周期上,我们可能无法尽可能早的定位和修复内存泄露问题。自动化可以在不需要更多开发者的情况下,更快的找到内存泄露。 博文链接:http://ifujun.com/yi-wen-zai-iosshang-zi-dong-jian-ce-nei-cun-xie-lu/原文链接:https://code.facebook.com/posts/5839463...

    miguel.jiang 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<