zoukankan      html  css  js  c++  java
  • 面试汇总——怎么检测浏览器中的内存泄露。

    本文是面试汇总分支——怎么检测浏览器中的内存泄露。

    本文转自:javascript内存泄露及谷歌浏览器查看内存使用

    前言

    今天写一下javascript导致内存泄露的几种方式,及我们在平时工作中,如何通过谷歌浏览器查看内存使用情况。我前面的文章制作公司数据大屏的几点技术总结 ,里面用到了不少setInterval,setInterval用多了,会占用大量的内存,要我们必须及时清理,否则,运行时间一长,极有可能导致浏览器崩溃!

    几种常见的js内存泄露

    1、意外的全局变量

    JavaScript 处理未定义变量的方式比较宽松:未定义的变量会在全局对象创建一个新变量。在浏览器中,全局对象是 window 。

    例如:

    haorooms ="这是一个全局的haorooms"

    实际上生成了一个全局的haorooms,虽然一个简单的字符串,无伤大雅,也泄露不了多少内存,但是我们在编程中尽量少的避免全局变量!

    另外一种全局变量可能由this创建。例如:

    function foo() {
        this.variable = "potential accidental global";
    }
    // Foo 调用自己,this 指向了全局对象(window)
    foo();

    2、没有及时清理的计时器或回调函数

    本文刚刚开始的时候,我就说了setInterval用多了,会占用大量的内存。因此setInterval我们必须及时清理!可以用如下方式清理setInterval。

    function b() {
        var a = setInterval(function() {
            console.log("Hello");
            clearInterval(a);
            b();                
        }, 50);
    }
    b();

    或者用2个函数:

    function init()
    {
        window.ref = window.setInterval(function() { draw(); }, 50);
    }
    function draw()
    {
        console.log('Hello');
        clearInterval(window.ref);
        init();
    }
    init();​

    或者我们用setTimeout

    function time(f, time) {
        return function walk() {
         clearTimeout(aeta);
            var aeta =setTimeout(function () {
                f();
                walk(); 
            }, time);
        };
    }
    
    time(updateFormat, 1000)();

    3、脱离 DOM 的引用

    有时,保存 DOM 节点内部数据结构很有用。假如你想快速更新表格的几行内容,把每一行 DOM 存成字典(JSON 键值对)或者数组很有意义。此时,同样的 DOM 元素存在两个引用:一个在 DOM 树中,另一个在字典中。将来你决定删除这些行时,需要把两个引用都清除。

    var elements = {
        button: document.getElementById('button'),
        image: document.getElementById('image'),
        text: document.getElementById('text')
    };
    function doStuff() {
        image.src = 'http://some.url/image';
        button.click();
        console.log(text.innerHTML);
        // 更多逻辑
    }
    function removeButton() {
        // 按钮是 body 的后代元素
        document.body.removeChild(document.getElementById('button'));
        // 此时,仍旧存在一个全局的 #button 的引用
        // elements 字典。button 元素仍旧在内存中,不能被 GC 回收。
    }

    4、闭包

    闭包注意事项我之前提及过,请看文章 http://www.haorooms.com/post/qianduan_xnyhbc

    5、echart不停调用导致内存泄露

    不停的用setInterval调用echart,更新echart表格及地图数据,及时清理了setInterval,也会导致内存泄露!

    解决办法:

    首先及时清理:

        myChart.clear();
        myChart.setOption(option);

    但是你会发现,作用不大,那么如何处理呢?

    我是如下做的:

    第一次处理用

        myChart.clear();
        myChart.setOption(option);

    后面用setInterval的时候,我是如下写的:

                                mapCharts.setOption({
                                    series: [{
                                            data: _this.convertData(mapdata)
                                        }, {
                                            data: _this.convertData(mapdata.sort(function (a, b) {
                                                return b.value - a.value;
                                            }).slice(1, 6)),
                                        }, {
                                            data: _this.convertData(mapdata.sort(function (a, b) {
                                                return b.value - a.value;
                                            }).slice(0, 1))
                                        }]
                                },{notMerge: false, lazyUpdate: false, silent:false});

    仅仅重新设置了series里面的数据,不是全部setOption(option);这样就不会内存泄露了!

    谷歌浏览器查看内存使用

    使用 Chrome 任务管理器作为内存问题调查的起点。 任务管理器是一个实时监视器,可以告诉您页面当前正在使用的内存量。

    按 Shift+Esc 或者转到 Chrome 主菜单并选择 More tools > Task manager,打开任务管理器。

    enter image description here

    使用 Timeline 记录可视化内存泄漏

    使用 Chrome DevTools 的 Timeline 面板可以记录和分析您的应用在运行时的所有活动。 这里是开始调查应用中可觉察性能问题的最佳位置。

    enter image description here

    Timeline 面板包含以下四个窗格:

    1、Controls。开始记录,停止记录和配置记录期间捕获的信息。

    2、Overview。 页面性能的高级汇总。

    FPS。每秒帧数。绿色竖线越高,FPS 越高。 FPS 图表上的红色块表示长时间帧,很可能会出现卡顿。

    CPU。 CPU 资源。此面积图指示消耗 CPU 资源的事件类型。

    NET。每条彩色横杠表示一种资源。横杠越长,检索资源所需的时间越长。 每个横杠的浅色部分表示等待时间(从请求资源到第一个字节下载完成的时间)。

    3、火焰图。 CPU 堆叠追踪的可视化。

    您可以在火焰图上看到一到三条垂直的虚线。蓝线代表 DOMContentLoaded 事件。 绿线代表首次绘制的时间。 红线代表 load 事件。

    enter image description here

    深色部分表示传输时间(下载第一个和最后一个字节之间的时间)。

    横杠按照以下方式进行彩色编码:

    HTML 文件为蓝色。

    脚本为黄色。

    样式表为紫色。

    媒体文件为绿色。

    其他资源为灰色。

  • 相关阅读:
    FastDFS 与 Nginx 实现分布式图片服务器
    git(三) 使用github
    html表单笔记
    Jquery笔记和ajax笔记
    CSS笔记
    javascript笔记
    idea笔记
    spring boot 框架设计步骤
    spring boot启动项的问题
    Loading class `com.mysql.jdbc.Driver'. The new driver class is `com.mysql.cj.jdb 问题
  • 原文地址:https://www.cnblogs.com/yadongliang/p/10677532.html
Copyright © 2011-2022 走看看