zoukankan      html  css  js  c++  java
  • javascript性能优化

    1.垃圾回收(Garbage collection)

    a.对象创建

    初始化赋值:
    
    var n = 123; // allocates memory for a number
    var s = 'abc'; 
    var a = [1, null, 'aaa']; 
    实例化对象
    
    var d = new Date();

    b.javascript垃圾回收,内存出现泄漏一般都发生在回收阶段.

    低级语言,需要手动管理内存的分配和释放,javascript作为一种高级语言,垃圾回收器,当对象创建时会自动分配内存,当对象不再被使用的时候会自动释放内存。 如果一个对象不再被引用,就会被GC回收。

    http://newhtml.net/v8-garbage-collection/

    Mark-and-sweep 算法:

    此算法中,会有roots,Garbage-collector 会定期的从这些roots开始查找,查找所有被roots引用的对象或者被这些对象引用的对象(对象被roots引用或者被其它对象引用,就表示还在使用),所有不可到达的对象(没有找到),会被GC回收。

    https://developer.mozilla.org/en-US/docs/Web/JavaScript/Memory_Management 

    内存分代: 

    脚本中,绝大多数对象的生存期很短,只有某些对象的生存期较长。为利用这一特点,V8将堆进行了分代。对象起初会被分配在新生区(通常很小,只有1-8 MB,具体根据行为来进行启发)。在新生区的内存分配非常容易:我们只需保有一个指向内存区的指针,不断根据新对象的大小对其进行递增即可。当该指针达到了新生区的末尾,就会有一次清理(小周期),清理掉新生区中不活跃的死对象。对于活跃超过2个小周期的对象,则需将其移动至老生区。老生区在标记-清除或标记-紧缩(大周期)的过程中进行回收。大周期进行的并不频繁。一次大周期通常是在移动足够多的对象至老生区后才会发生。至于足够多到底是多少,则根据老生区自身的大小和程序的动向来定。

    2.如何使用诊断工具发现性能问题

    a.任务管理器

    a.timeline

    释放过之后

    b.Take Heap Snapshot:页面中JavaScript对象和dom节点的内存分配。

      Summary

      Comparison

      Containment

      Statistics

    c.Record Javascript CPU Profile:记录每个函数的执行时间,Self Time,Total Time

    d.Record Allocation Timeline:记录堆上构造函数的内存分配,每个构造函数对应的实例数量,浅层大小,保留大小

    e.Record Allocation Profile:记录每个函数的内存使用大小。

     


    举个例子:

    <!DOCTYPE html>
    <html>
    <head lang="en">
      <meta charset="UTF-8" />
      <meta content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0;" name="viewport" >
      <title>index page</title>
        
    </head>
    <body>
    <input type="button" value="buttoon" id="btn" />
    <script type="text/javascript">
    // var btn=document.getElementById("btn");
    // btn.addEventListener("click",function(){
    
                  var ClassA = function(name){
                            this.name = name;
                            this.func = null;
                    };
    
                    var a = new ClassA("a");
                    var b = new ClassA("b");
    
                    b.func = bind(function(){
                            console.log("I am " + this.name);
                    }, a);
    
                    b.func();        //输出 I am a
                    //a = null;        //释放a
    
                    //b = null;        //释放self
    
                    //模拟上下文绑定
                    function bind(func, self){
                            return function(){
                                    return func.apply(self);
                            };
                    };
    
    
    // },false);
    
    
    </script>
    </body>
    </html>
    View Code

    由于,a和b都没有释放,可以看到classA下面有两个实例。a 实例的引用关系可以在Retainers 窗口中看到。a是通过self这个形参传入的,返回是个函数,又被func引用,func又是b的属性。

    释放a之后的内存:a虽然已经是null,但是a仍然被b引用,所以不会释放。

     正确做法:a和b都是null,才会释放。

    3.常见的性能问题

     a.局部变量意外变成全局变量

     b.闭包,用过没有释放

     c.setTimeout 没有释放

     d.事件绑定之后,不再需要时,没有移除

    学习资料:

    profile使用:

    https://www.2cto.com/kf/201402/281855.html

    https://blog.csdn.net/taoerchun/article/details/51480949

    原理及总体分析:

    http://www.ayqy.net/blog/js%E5%86%85%E5%AD%98%E6%B3%84%E6%BC%8F%E6%8E%92%E6%9F%A5%E6%96%B9%E6%B3%95/

    内存泄漏排查步骤:

    1.timeline 查看实时内存,是否不断上升(手动GC)。如果不断上升,说明可能存在内存泄露。

    2.记录开始对快照,隔段时间的对快照,compare一下,找出内存泄漏的点。

    3.如果明确知道某些操作会导致卡顿或者页面挂掉,可以在操作前后各记录一次对快照,进行对比。找出内存泄漏点。

  • 相关阅读:
    打开安装 好的Microsoft Dynamics CRM 4.0 报错误为 Caller does not have enough privilege to set CallerOriginToken to the specified value 的解决办法
    基于 Windows Server 2008 的计算机对 Microsoft Dynamics CRM 4.0 的支持
    Microsoft Dynamics CRM 4.0 如何添加自定义按钮
    Microsoft Dynamics CRM 4.0 Plugin 取值,赋值,查询
    C# 中的 enum(枚举) 类型使用例子
    vue事件的绑定
    表单验证2
    node中模块
    node模块的引入
    node中的读文件
  • 原文地址:https://www.cnblogs.com/bg57/p/6760512.html
Copyright © 2011-2022 走看看