首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

vue前端项目内存泄漏的处理过程

问题背景

在前端开发中,错误地使用全局变量和定时器等技术容易造成内存泄漏。一般来说,浏览器的内存泄漏对于多页应用程序来说并不是什么问题。用户在页面之间切换,每次页面切换都会引起浏览器刷新,即使页面上有内存泄漏,在页面 刷新后泄漏就解除了,由于泄漏的范围比较小,因此开发人员常常忽视这个问题。ADCloud前端项目在年初的时候进行了重构,框架升级等工作,引入了vue-route等技术,将多页应用改成了单页应用。当我们将ADCloud应用改造为单页应用后页面不会刷新,并且要处理很多 UI 操作,而且由于业务需要页面中还设置了大量定时器。如果发生内存泄漏,问题就会比较严重,轻则影响页面性能,重则导致页面崩溃。

内存泄漏是如何产生的

程序的运行需要内存,当程序提出要求时候,操作系统会供给内存。程序语言内存生命周期基本是一致的:分配内存,使用内存,释放内存。如果不再用到的内存,没有及时释放,就叫做内存泄漏。

在C语言中,内存使用完毕后必须手动释放内存,这很麻烦,所以大多数语言,会提供自动内存垃圾回收机制,减轻程序员的负担。JS也具有垃圾回收机制,执行环境会负责管理代码执行过程中使用的内存,找出那些不再继续使用的变量,然后释放其占用的内存。具体到浏览器中的实现通常有两个策略:引用计数,标记清除

引用计数算法简化定义为“该对象有没有其他对象引用到它”。如果没有引用指向该对象,则该对象将被垃圾回收机制回收。

引用计数的缺陷:循环应用。循环引用指的是对象A中包含一个指向对象B的引用,而对象B中也包含一个指向对象A的引用。请看下面例子:

该方式常常造成对象被循环引用时内存发生泄漏, 因此现在的浏览器弃用了这种算法而通过使用标记清除算法, 来解决这一问题。

标记清除:这个算法把"对象是否不再需要"简化定义为"对象是否可以获得"。算法假定设置一个叫做根root的对象(在Javascript里,根是全局对象)。定期的,垃圾回收器将从根开始,找所有从根开始引用的对象,然后找这些对象引用的对象,从根开始,垃圾回收器将找到所有可以获得的对象和所有不能获得的对象。如下图d对象无法获得,则该对象将被垃圾回收机制回收。

虽然JS具有垃圾回收机制,我们很少去直接去做内存管理,但是我们在写代码的时候,也要有内存管理的意识,谨慎的处理可能会造成内存泄漏的场景。因为应用最终要与操作系统打交道,运行在内存大小固定的硬件上。如果开发人员不关注内存管理,即使是最新的垃圾回收算法,也无法智能回收所有极端的情况。以下就是几种常见的案例。

ADCloud开发中遇到的内存泄漏

未销毁定时器和回调函数导致内存泄漏

ADCloud中有很多持续集成流水线,当流水线进行构建的时候,为了让用户能实时的看到流水线运行的情况,我们在流水线上增加了流水进度条.为了体现节点动态进行,我们给执行中的节点增加了一个计时器,并且做了一个持续奔跑的小人.这些效果是通过各级嵌套的定时器实现的。

在ADCloud完成单页应用改造后,有用户反映系统使用一段时间后出现卡顿的问题.后来经过排查,发现切换到其他页面后,原来的定时器并没有销毁,再切回流水线页面时候,又重新生成了定时器,这样浏览器中就有了大量重复的定时器, 不但定时器无法被内存回收, 定时器函数中的依赖也无法回收。

闭包

在开发中, 我们会经常用到闭包,比如图上的例子,多种操作使用同一个接口,不同操作使用操作编号来区分,因此我们使用闭包,来给每个按钮绑定事件。

下面这种情况下, 闭包会造成内存泄露:

这段代码,每次调用replaceThing时,theThing获得了包含一个巨大的数组和一个对于新闭包someMethod的对象. 同时unused是一个引用了originalThing的闭包。

这个关键在于, 闭包之间是共享作用域的, 尽管unused可能一直没有被调用, 但是someMethod 可能会被调用, 就会导致内存无法对其进行回收. 当这段代码被反复执行时, 内存会持续增长。

意外设置全局变量

在流水线的设置页面种,需要调接口获取流水线数据,流水线的数量很多,流水线下还有许多节点,每个节点又包含很多命令,获取的数据量会特别大,我们会将其赋值给一个变量以便后续使用。

在JS 中处理未被声明的变量,图中的pipeData, 会被定义到全局对象中, 在浏览器中就是window上。在页面中的全局变量, 只有当页面被关闭后才会被销毁。如果经常这些全局变量用来暂存大量的数据,而没有及时释放就会造成内存泄漏。

总 结

随着ADCloud项目的推进,前端应用的复杂性也日益增加,其性能优化的重要性越来越突出。虽然JS具有内存自动管理机制,我们开发也需要关注内存的使用以及回收,避免因为内存泄漏这类问题,而对用户的使用造成影响。

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20180604G0LIR500?refer=cp_1026
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码

添加站长 进交流群

领取专属 10元无门槛券

私享最新 技术干货

扫码加入开发者社群
领券