前言:JavaScript 有完善的内存处理机制,能自动进行垃圾回收,但是假如一个对象一直被引用,他的内存是无法得到释放的。如果项目运行过程中,内存占用越来越高,只增不减,没有峰值,就存在内存泄漏。多页应用我们可以通过页面刷新缓解,但是对于服务端渲染和单页应用则需要重点关注内存泄漏问题。本文主要以Vue单页应用展开,因为在 SPA 的设计中,用户使用它时是不需要刷新浏览器的,所以 JavaScript 应用需要自行清理组件来确保垃圾回收以预期的方式生效。
什么是内存泄漏
程序的运行需要内存。只要程序提出要求,操作系统或者运行时就必须供给内存。对于持续运行的服务进程,必须及时释放不再用到的内存。否则,内存占用越来越高,轻则影响系统性能,重则导致进程崩溃。不再用到的内存,没有及时释放,就叫做内存泄漏。
如何判断内存泄漏
Chrome浏览器memory有3种方式,可以分析内存:
-
Heap snapshot - 用以打印堆快照,堆快照文件显示页面的 javascript 对象和相关 DOM 节点之间的内存分配
-
Allocation instrumentation on timeline - 在时间轴上记录内存信息,随着时间变化记录内存信息。
-
Allocation sampling - 内存信息采样,使用采样的方法记录内存分配。此配置文件类型具有最小的性能开销,可用于长时间运行的操作。它提供了由 javascript 执行堆栈细分的良好近似值分配。
如何定位内存泄漏
常见的内存泄漏
-
意外的全局变量
函数中意外的定义了全局变量,每次执行该函数都会生成该变量,且不会随着函数执行结束而释放;
-
未清除的定时器
定时器没有清除,它内部引用的变量,不会被释放;
-
脱离DOM的元素引用
一个dom容器删除之后,变量未置为null,则其内部的dom元素则不会释放; -
持续绑定的事件
函数中addEventListener绑定事件,函数多次执行,绑定