在前端项目(PC端)中,定位内存泄漏往往比修复更难。尽管谷歌浏览器提供了Memory工具,但面对成千上万的元素和错综复杂的引用关系,开发仍然很难快速定位到有问题的代码块。1.什么是内存泄漏?系统进程不再使用的内存没有及时释放,称为内存泄漏。当内存占用越来越高时,轻则影响系统性能,重则导致进程崩溃。Chrome限制了浏览器可以使用的内存上限(64位是1.4GB,32位是1.0GB),这意味着浏览器将无法直接操作一些大内存对象。V8引擎在进行垃圾回收时,会阻塞JavaScript应用逻辑,重新执行JavaScript应用逻辑,直到垃圾回收结束。这种行为称为“停止世界”。如果V8的堆内存是1.5GB,V8做一次小垃圾回收需要50ms以上,造成假死。2.JS内存管理和垃圾回收机制GC高级语言基本上都有垃圾回收机制(garbagecollection)来自动管理内存,减轻程序员的负担,达到解决内存泄漏的目的,但是不允许手动触发和内存管理任何干预措施。旧版浏览器采用引用计数方式(ReferenceCounting)来管理内存,即每次引用加一,释放时减一。当这个值的引用计数变为0时,它的内存空间就可以被回收了。缺点是循环引用时不能回收。现代浏览器基本都是采用mark-and-sweep的方式来管理内存,即浏览器周期性地从某个根元素(比如window对象)开始寻找引用变量以及这些变量所引用的变量,从而使其始终发现下降。能找到的变量就是可用变量,找不到的变量会被内存回收。缺点是内存在清空后会产生很多细粒度的block,所以派生出mark-organization的方法,不再赘述。3、VUE中容易出现内存泄漏的几种情况。内存泄漏是一个累积的过程。只有当页面的生命周期稍长时,问题才会暴露出来。频繁的互动可以加快积累的过程。问题暴露了(所谓刷新可以满血复活)。所以很多时候,我们都是被动的等待问题暴露出来,然后再进行排查。主动分析通常比较困难。Vue页面大多是单页应用,交互性强,停留时间长。如果处理不当,很容易发生内存泄漏。本文主要针对自由dom对象的考察,普通JS变量的考察有时间会补充。1.全局变量引起的内存泄漏这个页面的dom对象在全局window对象中被引用name:'home',node:document.getElementById('home')}}}按Heapsnapshots键,搜索Detached,发现有没有dom脱离文档树元素,属于正常现象,换个路由跳转到其他页面,按Heapsnapshots键,搜索Detached,发现当前页面有两个dom元素浮在外面,它很明显,window对象引用了主页中的div,即使这个时候主页已经被销毁,home中的dom元素仍然驻留在内存中,无法释放。解决方法是在页面卸载的时候顺便处理掉引用。
