<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>檬檬前端行 &#187; 内存泄露</title>
	<atom:link href="http://www.frontendcodes.com/?feed=rss2&#038;tag=%E5%86%85%E5%AD%98%E6%B3%84%E9%9C%B2" rel="self" type="application/rss+xml" />
	<link>http://www.frontendcodes.com</link>
	<description>路漫漫其修远兮</description>
	<lastBuildDate>Wed, 18 Mar 2015 10:05:27 +0000</lastBuildDate>
	<language>zh-CN</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.4.2</generator>
		<item>
		<title>对JS内存泄露的一些思考</title>
		<link>http://www.frontendcodes.com/?p=76</link>
		<comments>http://www.frontendcodes.com/?p=76#comments</comments>
		<pubDate>Mon, 21 Feb 2011 14:34:07 +0000</pubDate>
		<dc:creator></dc:creator>
				<category><![CDATA[前端]]></category>
		<category><![CDATA[内存泄露]]></category>

		<guid isPermaLink="false">http://www.frontendcodes.com/?p=76</guid>
		<description><![CDATA[昨天在群里和西门，天天讨论js的内存泄露问题。 JS的内存泄露，无怪乎就是从DOM中remove了元素，但是依然有变量或者对象引用了该DOM对象。然后内存中无法删除。使得浏览器的内存占用居高不下。这种内存占用，随着浏览器的刷新，会自动释放。 而另外一种情况，就是循环引用，一个DOM对象和JS对象之间互相引用，这样造成的情况更严重一些，即使刷新，内存也不会减少。这就是严格意义上说的内存泄露了。 感谢天天，提供了IE6给我们的脚本进行测试，然后我们发现IE6的内存泄露问题确实特别严重，而我的IE8下不会出现的问题，在IE6下反而很容易出现。 首先，我写了一个制造一个大DOM对象的函数。很简单，就是给DOM对象增加了一个很大很大的属性。恩。几MB function MemoryLeak(){ var p=document.createElement(&#8220;p&#8221;); p.bigAttribute=new Array(1000).join(new Array(1000).join(&#8220;xxxx&#8221;)); } 一百万个XXXX，几个MB，恩 首先，一个明显的循环引用。 function MemoryLeak(){ var o={}; o.p=document.createElement(&#8220;p&#8221;); o.p.bigAttribute=new Array(1000).join(new Array(1000).join(&#8220;xxxx&#8221;)); o.p.e=o; } 这个肯定没问题，js对象o和DOM对象p之间形成了相互引用。 在IE6下，内存溢出了，即使刷新，内存占用也不会下降。在我的IE8下，内存不会增加。IE8改进了不少问题嘛。窃喜中。。。 西门提供了一个函数，也是会造成IE6的内存溢出。 function leak_ximen(){ var fn = function(){}; var obj = document.createElement(&#8220;div&#8221;); obj.bigAttribute=new Array(1000).join(new Array(1000).join(&#8220;xxx&#8221;)); obj.onclick = fn; } 这个函数的内存溢出问题很隐蔽。事实上，DOM元素通过onclick引用了一个function，而function的active object引用了变量obj，而变量obj又引用了DOM元素。于是形成了一个环形引用。IE6又一次出现了问题。。。 西门又提供了另外一个方法。避免了这个问题。 function leak_ximen3(){ var fn = function(){}; (function() [...]]]></description>
			<content:encoded><![CDATA[<p>昨天在群里和西门，天天讨论js的内存泄露问题。</p>
<p>JS的内存泄露，无怪乎就是从DOM中remove了元素，但是依然有变量或者对象引用了该DOM对象。然后内存中无法删除。使得浏览器的内存占用居高不下。这种内存占用，随着浏览器的刷新，会自动释放。</p>
<p>而另外一种情况，就是循环引用，一个DOM对象和JS对象之间互相引用，这样造成的情况更严重一些，即使刷新，内存也不会减少。这就是严格意义上说的内存泄露了。</p>
<p>感谢天天，提供了IE6给我们的脚本进行测试，然后我们发现IE6的内存泄露问题确实特别严重，而我的IE8下不会出现的问题，在IE6下反而很容易出现。</p>
<p>首先，我写了一个制造一个大DOM对象的函数。很简单，就是给DOM对象增加了一个很大很大的属性。恩。几MB</p>
<p>function MemoryLeak(){</p>
<p>var p=document.createElement(&#8220;p&#8221;);</p>
<p>p.bigAttribute=new Array(1000).join(new Array(1000).join(&#8220;xxxx&#8221;));</p>
<p>}</p>
<p>一百万个XXXX，几个MB，恩</p>
<p>首先，一个明显的循环引用。</p>
<p>function MemoryLeak(){</p>
<p>var o={};</p>
<p>o.p=document.createElement(&#8220;p&#8221;);</p>
<p>o.p.bigAttribute=new Array(1000).join(new Array(1000).join(&#8220;xxxx&#8221;));</p>
<p>o.p.e=o;</p>
<p>}</p>
<p>这个肯定没问题，js对象o和DOM对象p之间形成了相互引用。</p>
<p>在IE6下，内存溢出了，即使刷新，内存占用也不会下降。在我的IE8下，内存不会增加。IE8改进了不少问题嘛。窃喜中。。。</p>
<p>西门提供了一个函数，也是会造成IE6的内存溢出。</p>
<div id="_mcePaste">function leak_ximen(){</div>
<div id="_mcePaste">var fn = function(){};</div>
<div id="_mcePaste">var obj = document.createElement(&#8220;div&#8221;);</div>
<div id="_mcePaste">obj.bigAttribute=new Array(1000).join(new Array(1000).join(&#8220;xxx&#8221;));</div>
<div id="_mcePaste">obj.onclick = fn;</div>
<div id="_mcePaste">}</div>
<p>这个函数的内存溢出问题很隐蔽。事实上，DOM元素通过onclick引用了一个function，而function的active object引用了变量obj，而变量obj又引用了DOM元素。于是形成了一个环形引用。IE6又一次出现了问题。。。</p>
<p>西门又提供了另外一个方法。避免了这个问题。</p>
<p>function leak_ximen3(){</p>
<p>var fn = function(){};</p>
<p>(function() {</p>
<p>var obj = document.createElement(&#8220;div&#8221;)</p>
<p>obj.bigAttribute=new Array(1000).join(new Array(1000).join(&#8220;xxx&#8221;));</p>
<p>obj.onclick = fn;</p>
<p>})();</p>
<p>}</p>
<p>fn作为一个函数，这样就无法引用到obj，不会造成内存泄露。</p>
<p>通过这次讨论，突然觉得IE6很可怕。因为这样的内存溢出方式，在平时的代码编写中，经常这样做了。从来没有想过可能导致的问题。而西门的解决方案，从代码编写上，这样做又不现实，真的很麻烦，为了防止这种事情，只能在remove的时候，让onclick为null，显性的切断引用链。</p>
<p>一声叹息：其一，所有的remove都要这么做，工作量真不是一般的大，其二，还有很多事件是通过attachEvent/addEventListener的方式添加的，而JS没有提供一种清空这种事件绑定的方式，为之奈何啊。。。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.frontendcodes.com/?feed=rss2&#038;p=76</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>
