最近做一個公司的業務系統,公司要求能盡可能的與c/s近似,也就是如c/s一樣,點擊文本框可以彈出此項目的相關內容,進行選擇輸入。
我使用了彈出窗口,然后在子窗口雙擊選中項目,把選中的值返回給父窗體。
在系統做完了之后,在客戶使用的過程,由於客戶使用的是512m的內存配置,所以在打開了30--40個窗體之后,ie的虛擬內存占用量達到近200m,從而使系統變慢,javascript的運行也變慢了。
在google搜了一下之后,才知道可能是由於ie的內存泄漏引起的。具體可以參看中的相關文章。
我使用任務管理器,打開一個彈出窗口,ie內存就增加1-3m,然后關閉窗口,有時內存並不釋放,有時才釋放幾十k。看來問題出在了內存釋放上面。
接着按內存釋放這個思路,進行搜索查找方法,來進行解決這個問題。我找到一個javascript未公開的函數CollectGarbage,這個函數是用來進行內存釋放的。我在所有的彈出窗口結束之前把所有的自己定義的javasctip的變量設置為null,並調用CollectGarbage函數。
javascript中把變量設為null,javascript並不會把內存釋放,當下次再次定義變量時,就會覆蓋此變量所在的內存。如果不設為null,javascript再次定義變量時,會開辟一個新的內存空間。
在使用以上處理之后,再次打開窗口,ie的內存每次還是增加1-3m,但是在關閉窗口之后,則ie會釋放一定數量的內存在500k至2m。起到了一定的作用。
由於我在頁面中使用了第三方的控件,第三方的控件中的javascript中的內存是如何管理,就不是由我來控制的了。
1.javascript內存釋放的方法示例
把所有上級函數的參數即使設為null,並使用CollectGarbage來釋放內存。
示例
<script>
//32M
function AllocMem()
{
var str="12345678";
for(var i=3;i<24;i++)
str+=str;
return str;
}
function A(a)
{
a=null;
return r;
function r()
{
}
}
var f=A(AllocMem());
alert(1);
CollectGarbage();
//明顯,已經釋放了。
r=null;
alert(2);
CollectGarbage();
</script>
----------
里面對於內存釋放的規則(腳本層)已經理解得很透了。
(每一層菜單分配?M的內存.對着任務管理器才看到情況)
注:
CollectGarbage()通常會在核心推出內存,因就是IE或NS程序結束的時候才會調用.這樣才是安全的
說明:
1) 如果你在另一個window中keep了該window中的object的reference,即使關閉該window,內存也沒有釋放
As you might know, windows opened with window.open() may share a process with its opener (_blank or _new window may not). That is, even if you see those two windows on the desktop, if you look at the process table in the Task Manager, you may only see one IEXPLORE.EXE running. Memory may only be released when the process is terminated
2)更糟糕的是,如果你keep的是一個DOM object的reference, 關閉該object 所在window, IE會crash, 報內存錯誤(或者要求,重新啟動)
I would say this looks like a bug, you might want to report to Microsoft