`
babydeed
  • 浏览: 238810 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

动态加载Javascript会导致内存泄露? rss文章订阅

    博客分类:
  • Ext
阅读更多

前些天在javaeye上发了一个帖子,“动态加载Javascript会导致内存泄露?”,自己当时被老外的那篇文章搞的比较困惑,网上也请教了一些高人,这里要非常感谢那些帮助我的人,工作非常繁忙的时候还愿意给我讲解他们对问题的看法,真的让我很感动!

 

这里再介绍一个比较好用的工具:Drip/sIEve,感谢jindw为我推荐这个工具,DripsIEve的作者应该是同一个人,连open souce上的项目都是在一起的。不过,平时我们主要使用sIEve就可以了,sIEve的功能比Drip强大一些,sIEve 是一个帮助我们查看ie浏览器(他本身基于操作系统安装的ie内核)内存的使用和内存泄露问题的。具体使用很简单,这里再提供一个链接给大家:http://home.orange.nl/jsrosman/,大家下载下来后就可以使用了。

Firefox下面也有一个检查内存泄露的工具,不过我用过,感觉有时候很让人抓狂,大家有兴趣的不妨也试试。PuterJam为我们总结了一篇“javascript 内存泄露工具使用”,推荐去看看。

来看我做的测试,代码1

<body>

<script type="text/javascript">

script = document.createElement('script');

script.src = 'little.js';

script.id = 'JSONP';

script.type = 'text/javascript';

script.charset = 'utf-8';

var head = document.getElementsByTagName('head')[0];

head.appendChild(script);

</script>

测试页面2

<script type="text/javascript">

var script = document.getElementById('JSONP');

script.parentNode.removeChild(script);

</script>

</body>

sIEve的结果是:



 

可以看到,id=JSONP的节点是孤立状态,而没有被回收 (还有一个孤立节点 大家不用管) ,为了解决这个办法,从EXTjs里面的代码得到灵感:


 

我把页面代码修改成:

<body>

<script type="text/javascript">

script = document.createElement('script');

script.src = 'little.js';

script.id = 'JSONP';

script.type = 'text/javascript';

script.charset = 'utf-8';

var body = document.getElementsByTagName('body')[0];

body.appendChild(script);

</script>

测试页面2

<script type="text/javascript">

var script = document.getElementById('JSONP');

var d = document.createElement('div');

d.appendChild(script);

d.innerHTML = '';

</script>

</body>

       可惜的是竟然还是存在没被回收的节点,囧!:


 

这里我暂时还不知道是什么原因,没仔细研究下去,如果是div的话,用这种方式是可以把节点回收的。

克军大牛跟我讲,“再加一行script = null;确实jsonp不能滥用,,一般解决dom的循环reference就是null掉”,于是我把最后的script对象null掉,发现果然节点不存在了!

       Code

<body>

<script type="text/javascript">

script = document.createElement('script');

var head = document.getElementsByTagName('head')[0];

head.appendChild(script);

script.src = 'little.js';

script.id = 'JSONP';

script.type = 'text/javascript';

script.charset = 'utf-8';

</script>

测试页面2

<script type="text/javascript">

var script = document.getElementById('JSONP');

script.parentNode.removeChild(script);

script = null;

</script>

</body>

结果图:


 

       看来还是不能想什么奇淫技巧,老老实实把最后的对象引用null

ranklau那天抽出时间跟我讲:“如果用htmlelementremove后会泄露。用fragmentfragment不用appendDOM上,不会有泄露。一个节点appenddom上,你再移除它就会有泄露的。所以才会出现象exttrash机制”,ranklau一看就是高手,我也是陋闻了,这些结论竟然都不知道!不过ranklau也是技术人员一贯的严谨作风,自己没去做测试,所以希望我能去做测试验证这些观点。今天上网找到了这方面的一个帖子,发现“这是IE的一个特点:document fragmentappenddocumentdom里面的时候,也可以拥有自己的脚本运行空间,可以用script标签发起请求。这样用document fragment就可以比iframe使用更少的客户端资源来完成操作。”好!做测试:

<body>

<script type="text/javascript">

var df = document.createDocumentFragment();

script = document.createElement('script');

script.src = 'little.js';

script.id = 'JSONP';

script.type = 'text/javascript';

script.charset = 'utf-8';

df.appendChild(script);

</script>

测试页面2

<script type="text/javascript">

var script = document.getElementById('JSONP');

alert(script);

</script>

</body>

测试结果:



 

 

id=JSONP的节点至始至终没有append到页面的dom树上来,是一个孤立的点,但是,null掉后也就被回收了,所以,这种方式也不错!

       最后,我却怀疑这个documentFragment会引起内存泄漏,因为浏览器要为这个新节点产生一个新的脚本scope,所以肯定会消耗额外的内存,至于到底是不是这样,还是测试:

       Code

<body>

<script type="text/javascript">

for(var i=0;i<100;i++){

         var dom = document.createDocumentFragment();

         script = document.createElement('script');

         script.src = 'little.js';

         script.id = 'JSONP';

         script.type = 'text/javascript';

         script.charset = 'utf-8';

         dom.appendChild(script);    

         dom.removeChild(script);

         script=null;

}

</script>

</body>

        

如图,发现,还是存在额外的内存消耗

最后,看网上有人说“IE8beta版本不支持documentFragment拥有独立的运行空间,正式版又解决了这个问题”,这个我不确定,因为我至今没装IE8,大家有兴趣可以去测试下,不过我觉得比较稳妥的方式还是最好别用documentFragment

 

转自:http://04js.cn/content.asp?id=1613

今天自己再次做了一些测试,和上次不一样,这次集中在IE上面(上次在firefox测试比较多),这几天的请教让我明白:IEfirefoxchrome的解析机制是不一样的,“对于需要频繁动态加载的script(比如跨域的jsonp接口),可以对ie做一下专门的优化,因为ieDom解析机制是c++写的,好像属于windows网络堆栈的那个部分,跟Javascript引擎的垃圾回收机制完全不同,内存泄漏问题比较明显……”,“firefox的内存GC机制比IE强悍,不必作为重点考虑对象。只要ie的问题能处理好,firefox上基本上也没有什么问题。”

分享到:
评论
1 楼 tipx 2010-07-02  
学习了

相关推荐

    Android手机RSS阅读器html5.zip

    【Android手机RSS阅读器html5.zip】是一款专为Android平台设计的RSS阅读应用,它结合了HTML5技术,提供了一种高效、便捷的方式来获取和阅读RSS订阅源中的内容。这款应用充分利用了HTML5的特性,如离线存储、多媒体...

    rss-episode-filter:开始应用

    【标题】"RSS Episode Filter: 开始应用"指的是一个针对RSS(Really Simple Syndication) feed的筛选工具,可能是一个JavaScript项目,旨在帮助用户过滤和管理RSS订阅中的特定章节或剧集。RSS是一种标准,用于发布...

    网站三大经典模块!!!!!!!

    在ASP.NET中,可以使用主题和皮肤机制,预先定义好多种样式,根据用户选择动态加载。 总结起来,网站开发中的注册与登录、留言版和RSS订阅模块涉及到了用户认证、数据交互、内容管理等多个方面,而ASP.NET和C#提供...

    firefox chrome脚本

    4. **google_chrome_rss_icon.user.js**:这个脚本可能在Chrome浏览器中添加了一个功能,使得用户可以在支持RSS订阅的网站上快速找到并订阅RSS源。 5. **SmoothScroll.user.js**:这类脚本通常用于平滑滚动页面,...

    网络基本程序---新闻阅读器

    2. **RSS/Atom订阅**:许多新闻网站提供RSS(简易聚合)或Atom格式的订阅源,新闻阅读器通过解析这些XML文件获取最新的文章标题、摘要和链接。用户可以订阅感兴趣的新闻源,阅读器会自动检查更新并呈现内容。 3. **...

    网站访问速度优化提速方法

    - 在IIS中启用应用程序池的回收机制,避免长时间运行导致的内存泄漏问题。 - 在`web.config`文件中配置错误自定义处理(`&lt;customErrors mode="On" /&gt;`),以便更好地处理和报告错误信息。 - 将调试模式设置为关闭(`...

    工资查询系统首页

    新闻展示部分可能采用了RSS订阅或者API接口的方式,实时获取并更新新闻内容。这需要后端与外部新闻源进行通信,可能涉及到HTTP请求、JSON解析等技术。新闻数据通常存储在数据库中,以便快速检索和展示。 系统开发中...

    车源宝小程序,发布车源,寻车

    后台可能采用RSS订阅或爬虫技术收集信息,再通过内容管理系统(CMS)进行编辑和发布,同时推送通知至用户端,这涉及到了推送服务如极光推送或信鸽推送。 5. **微信小程序开发**:作为一款微信小程序,其开发遵循...

    JReader [beta]-crx插件

    与XML格式的RSS或Atom相比,JSON Feed采用JSON(JavaScript Object Notation)作为其数据载体,JSON是一种轻量级的数据交换语言,易于人类阅读和编写,同时也易于机器解析和生成。由于其简洁的语法,JSON Feed在开发...

    红色仿今日头条最新资讯阅读程序源码.zip

    4. **API接口**:为了获取和更新实时资讯,程序可能需要对接第三方API,例如RSS订阅服务、新闻聚合API或社交媒体API。 5. **用户体验(UX)和响应式设计**:确保程序在不同设备上(如手机、平板电脑和桌面电脑)都...

Global site tag (gtag.js) - Google Analytics