JavaScript 中的內存泄漏
JavaScript 是一種垃圾收集式語言,這就是說,內存是根據對象的創建分配給該對象的,並會在沒有對該對象的引用時由瀏覽器收回。JavaScript 的垃圾收集機制本身並沒有問題,但瀏覽器在爲 DOM 對象分配和恢復內存的方式上卻有些出入。
Internet
Explorer 和 Mozilla Firefox 均使用引用計數來爲 DOM
對象處理內存。在引用計數系統,每個所引用的對象都會保留一個計數,以獲悉有多少對象正在引用它。如果計數爲零,該對象就會被銷燬,其佔用的內存也會返回
給堆。雖然這種解決方案總的來說還算有效,但在循環引用方面卻存在一些盲點。
原因
1)循環引用導致了內存泄漏
<html>
<body>
<script type="text/javascript">
document.write("circular references between JavaScript and DOM!");
var obj;
window.onload = function(){
obj=document.getElementById("DivElement");
document.getElementById("DivElement").expandoProperty=obj;
obj.bigString=new Array(1000).join(new Array(2000).join("XXXXX"));
};
</script>
<div id="DivElement">Div Element</div>
</body>
</html>
2)
由外部函數調用引起的內存泄漏
<html>
<head>
<script type="text/javascript">
document.write(" object s between JavaScript and DOM!");
function myFunction(element)
{
this.elementReference = element;
// This code forms a circular reference here
//by DOM-->JS-->DOM
element.expandoProperty = this;
}
function Leak() {
//This code will leak
new myFunction(document.getElementById("myDiv"));
}
</script>
</head>
<body οnlοad="Leak()">
<div id="myDiv"></div>
</body>
</html>
3)
閉包引起的內存泄漏
function parentFunction(paramA){
var a = paramA;
function childFunction(){
return a + 2;
}
return childFunction();
}
4)
由事件處理引起的內存泄漏模式
<html>
<body>
<script type="text/javascript">
document.write("Program to illustrate memory leak via closure");
window.οnlοad=function outerFunction(){
var obj = document.getElementById("element");
obj.οnclick=function innerFunction(){
alert("Hi! I will leak");
};
obj.bigString=new Array(1000).join(new Array(2000).join("XXXXX"));
// This is used to make the leak significant
};
</script>
<button id="element">Click Me</button>
</body>
</html>
解決方法
1)打破循環引用
<html>
<body>
<script type="text/javascript">
document.write("Avoiding memory leak via closure by breaking the circular reference");
window.οnlοad=function outerFunction(){
var obj = document.getElementById("element");
obj.οnclick=function innerFunction()
{
alert("Hi! I have avoided the leak");
// Some logic here
};
obj.bigString=new Array(1000).join(new Array(2000).join("XXXXX"));
obj = null; //This breaks the circular reference
};
</script>
<button id="element">"Click Here"</button>
</body>
</html>
2)添加另一個閉包
<html>
<body>
<script type="text/javascript">
document.write("Avoiding a memory leak by adding another closure");
window.οnlοad=function outerFunction(){
var anotherObj = function innerFunction(){
// Some logic here
alert("Hi! I have avoided the leak");
};
(function anotherInnerFunction(){
var obj = document.getElementById("element");
obj.οnclick=anotherObj
})();
};
</script>
<button id="element">"Click Here"</button>
</body>
</html>
3)避免閉包自身
<html>
<head>
<script type="text/javascript">
document.write("Avoid leaks by avoiding closures!");
window.οnlοad=function(){
var obj = document.getElementById("element");
obj.onclick = doesNotLeak;
}
function doesNotLeak(){
//Your Logic here
alert("Hi! I have avoided the leak");
}
</script>
</head>
<body>
<button id="element">"Click Here"</button>
</body>
</html>
4)考慮用
CollectGarbage()
jcl.MemFree = function(Mem){
Mem = null;
CollectGarbage();
};
檢測軟件
sIEve
: 他是基於ie的內存泄露檢測工具,需要下載運行,
http://home.wanadoo.nl/jsrosman/
Leak Monitor
: 他是基於firefox的內存泄露檢測工具,https://addons.mozilla.org/firefox/2490/
個人建議
內存回收機制本身有問題,所以開發人員開發的時候儘量減少內存溢出。不要盲目的追求完美!
IE,firefox內存溢出原因與解決方法
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.