美文网首页
一次内存泄露排查

一次内存泄露排查

作者: JerryDai | 来源:发表于2018-05-29 20:46 被阅读12次

    项目背景

    后台在管理界面直接编辑js,然后前端直接运行加载此 js,并且此页面不会刷新(指定的 F5 这种刷新),而且是一直投影在屏幕上的。其中 js 分2部分,一部分是相对固定。一部分是动态的。前端通用不停的获取后台的 js 然后在实例化 js 来动态更新界面数据。

    方案

    直接使用 new Function 来动态解析后台填写的 js 脚本。demo 如下

    <html>
        <head>
            <h1></h1>
        
        </head>
        <script>
            //转换函数
            var convertToFn = function (fun) {
                return (new Function("return " + fun))();
            }
            var i = 0;
            setInterval(function(){
                var fn = convertToFn("{\
                                thisMap : {\
                                    thisFn : function(){\
                                        return 'aaa'\
                                    }\
                                }\
                            }");
                fn.thisMap.thisFn();
                i++;
                document.getElementsByTagName("h1")[0].innerHTML = i;
    //            console.log(fn.thisMap.thisFn())
            }, 10);
        </script>
    </html>
    

    项目上线后发现此方法非常损耗内存。上面的函数循环大约20000次之后占用内存 11MB 左右。并且一直不会释放。从而导致浏览器内存耗尽奔溃。下图有快照。

    20000次很快就花完的了,而且设置的是4秒一次。又不止一个图形在刷,有20+个。

    image

    曲线救国

    不在支持动态刷新固定的部分的 js,只做值的动态更新。进一步验证之后,此方式是可以有效控制内存不增长。demo 如下

    <html>
        <head>
            <h1></h1>
        </head>
        <script>
            //先使用 el 表达式输出到界面(或者使用 document.write 输出,再不济就用上面的 new Function 吧,只输出一次就好 )
            var data = {};
            
            var fn = function(){
                return {
                    thisMap : {
                        thisFn : function(){
                            return 'aaa'
                        },
                        getData : data
                    }
                }
            }
             
            var i = 0;
            setInterval(function(){
                //赋值给此变量,后面调用的时候就可以拿到最新的了
                data = Math.random(1000000)*100;
                i++;
                document.getElementsByTagName("h1")[0].innerHTML = i;
    //            console.log(fn().thisMap.getData)
            }, 10);
        </script>
    </html>
    

    下图为内存快照,开始有增长,后面基本就没有了


    image

    文章出自 http://blog.wordty.cn

    相关文章

      网友评论

          本文标题:一次内存泄露排查

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