美文网首页js基础
浏览器内存泄漏

浏览器内存泄漏

作者: 方_糖 | 来源:发表于2021-05-10 14:03 被阅读0次

内存泄漏的症状

  • 网页的性能效果会随着时间的推移逐渐变差:这可能是<u>内存泄漏</u>的症状。内存泄漏是使用过后不再使用的内存未被释放。

  • 网页的效果始终不佳:这可能是<u>内存膨胀</u>的症状。内存膨胀是指页面使用的内存过大。

  • 网页的效果延迟或频繁暂停: <u>频繁的垃圾回收</u>症状。浏览器决定何时回收内存。在回收内存期间,所有脚本执行都将暂停。

使用谷歌开发者工具分析内存泄漏

参考:chrome内存泄露(一)、内存泄漏分析工具

1. 查看整体内存占用

按Shift + Esc打开谷歌的<u>任务管理器</u>。或点击右上角菜单--更多工具---任务管理器。关注内存占用空间、javascript使用的内存。

image.png

操作步骤

  • 内存占用空间: 本机内存,如果这个值在增加,说明正在创建DOM节点
  • Javascript使用的内存:JS堆,跳动的数字表示网页上<u>活动对象</u>使用的内存,如果这个数字在增加,说明正在创建新对象或现有对象正在增长

什么是活动对象 ?
有引用的对象为可获得的对象,也称为活动对象。没有引用的对象是不可获得的对象,会被垃圾机制回收。
如:
var arr = new Array();
new Array()创建了一个新的数组对象,arr是它的引用,如果我们这时把arr = null
那数组对象就无法再被我们调用了,这时就会被当成垃圾回收

常见的几种情况及原因

(1)内存占用空间一直在增长,JavaScipt使用的内存没增长:浏览器还没有进行垃圾回收
(2)内存占用空间一直在增长,JavaScipt使用的内存增长很慢:JS变量引用了DOM,影响了其他DOM节点

2. Performance面板
2.png
  • 启用Memory(内存)复选框
  • 点击垃圾回收 -> 点击开始录制 -> 点击垃圾回收 -> 点击结束录制

会得到图如下


3.png

(1)Heap堆:曲线表示JS堆,在后面的Memory面板会重点说明
(2)Call stack 调用栈:横向表示调用时间,如果调用时间过长,就要进行优化。垂直方向无意义,主要表示函数嵌套较深。
(3)Counter 计数器:显示内存的使用情况,分别显示

  • JS Heap:JS堆
  • Documents:文档
  • Nodes: DOM 节点
  • Listeners:侦听器
  • GPU Memory:GPU内存

主要关注JS Heap、Nodes、Listeners。如果这三个中有一个在持续上涨,并且没有下降的趋势,就有可能是内存泄漏

3. Memory 面板
4.png

操作步骤

  • 选择快照堆类型:一般选Heap snapshot(JS堆快照)和Allocation instrumentation on timeline(JS堆分配时间线)
  • 点击垃圾回收 -> 开始录制
  • 录制完成后得到堆快照

Heap snapshot(JS堆快照):发现DOM泄漏
Allocation instrumentation on timeline(JS堆分配时间线): 显示了对象什么时候被创建,什么时候存在内存泄漏(蓝色线表示未回收、灰色线表示已回收)

视图类型

5.png
  • Summary: 总览视图,
    按构造函数分组。用于捕捉对象及其使用的内存。对于定位DOM内存泄露特别有用。

  • Comparison:对比视图
    用于对比不同操作之后的堆快照,查看内存的释放及引用计数,来分析内存是否泄露及其原因。

  • Containment:内容视图
    查看堆内容。更适合查看对象结构,有助于分析对象的引用情况。适用于分析闭包以及深入分析对象。

  • Statistics:统计视图
    总览堆的统计信息。

JS快照堆
以以下代码为例说明


<html>
    <head>
        <meta charset="utf-8">
    </head>
    <body>   
        <button id="createBtn">增加节点</button>
        <script>
            function create() {  
            var ul = document.createElement('ul');  
            for (var i = 0; i < 10; i++) {  
                var li = document.createElement('li');  
                ul.appendChild(li);  
            }  
            detachedNodes = ul;  
            }  
            document.getElementById('createBtn').addEventListener('click', create);
        </script>
    </body>
</html>

  • 多次录制对比堆快照

1、无任何操作,拍第一个堆快照
2、执行你觉得可能造成内存泄露的操作,再执行相反操作
3、拍第二个堆快照,切换到视图类型为Comparison(对比视图),并且指定与第一个堆快照对比
<u>记得每次录制之前要先点击垃圾回收</u>

如:
点击垃圾回收 => 打开页面后立即录制一次堆快照 => 点击按钮 => 点击垃圾回收 => 录制一次堆快照 => 选中一个堆快照切换视图类型为Comparison(对比视图)并与另一个快照进行比较


6.png

JS堆分配时间线
使用上面的例子,操作如下图

7.gif

高度代表这个对象的大小
颜色代表这个对象的内存释放情况:蓝色线代表在录制结束前未被回收的,灰色线代表已经被回收了。

我们可以重复执行某个动作,如果有不少蓝色柱被保留,那就发生了内存泄漏

选中某段时间内的时间线,可以具体分析在这个时间点变化的对象

8.png

常见的内存泄漏

参考: chrome内存泄露(二)、内存泄漏实例

1. 常见JS内存泄漏
  • 全局变量引起的内存泄漏
  • 闭包引起的泄漏
  • DOM删除时没有解绑事件
  • 定时器没有清除
2. Vue常见内存泄漏

相关文章

  • 【Android测试】内存泄漏检测 LeakCanary

    什么是内存泄漏和内存溢出?内存泄漏有什么危害?LeakCanary检测内存泄漏? 内存泄漏(Memory Leak...

  • JQ第八部分源码学习

    DOM元素与对象之间互相引用,大部分浏览器会出现内存泄漏 JQ中的data数据缓存就是解决这个内存泄漏的问题的,当...

  • 2018-03-16

    什么是内存泄漏 内存泄漏是指一块被分配的内存既不能被使用又不能被回收,直到浏览器的进程结束。 JS中的垃圾回收机制...

  • 为何每次用完ThreadLocal都要调用remove()?

    什么是内存泄漏 Key 的泄漏 Value 的泄漏 如何避免内存泄露 什么是内存泄漏 内存泄漏指的是,当某一个对象...

  • Android如何打造高质量的应用?( 三)

    内存泄漏内存泄漏简单来说就是没有回收不再使用的内存,排查和解决内存泄漏也是内存优化无法避开的工作之一。很多内存泄漏...

  • JS垃圾回收机制和内存泄漏

    一、浏览器内存泄漏 浏览器封装的V8引擎支持对JS进行解析,当程序运行(runtime)时,只要程序提出需要内存,...

  • 浏览器内存泄漏

    内存泄漏的症状 网页的性能效果会随着时间的推移逐渐变差:这可能是 内存泄漏 的症状。内存泄漏是使用过后不再使用的内...

  • Android内存泄漏场景及解决方法

    本文包括以下内容: 内存泄漏原理 Android内存泄漏发生的情况 检测内存泄漏的工具、方法 如何避免内存泄漏 更...

  • 内存泄漏

    什么是内存泄漏引起内存泄漏的原因野指针,空指针,僵尸对象 1.什么是内存泄漏 内存泄漏(Memory Leak)是...

  • 性能优化——内存泄漏(3)代码分析篇

    内存泄漏系列文章:性能优化——内存泄漏(1)入门篇性能优化——内存泄漏(2)工具分析篇性能优化——内存泄漏(3)代...

网友评论

    本文标题:浏览器内存泄漏

    本文链接:https://www.haomeiwen.com/subject/xdzrdltx.html