2010-10-31 42 views
26

背景不會發生垃圾回收:我目前工作的一個內部網站,它利用了MochaUI庫(從virtual desktop demo工作)的。我使用的是Mootools 1.2.4和MochaUI 0.9.7。在我的「虛擬桌面」實現中打開的窗口通過iframe加載其內容。一些加載的頁面在CSS和腳本方面非常重要,因此當用戶關閉窗口時,必須充分收集Window對象,這一點很重要。這顯然是由圖書館照顧的(它在使用Firefox時確實做得很好)。鉻未能釋放內存,如預期(Mootools的/ MochaUI庫)

更新 最初發布的問題已經變得過長,從後續的編輯/更新。標題不再準確,所以我改變了這一點。此外,請參閱我的答案以獲取部分解決方案。

以下是要點:

  1. 鉻糊里糊塗像這樣:

    • 鉻失敗時,他們關閉,以釋放分配給MochaUI窗口對象的內存。相反,Chrome的內存使用率會在窗口完成加載其iframe內容後達到的級別上凍結(字面上),並設置內存使用的下限,直到頁面刷新。
    • 隨着窗口打開/關閉,進程所使用的內存繼續增加。最終,達到了某種類型的上限,並且內存使用率停止攀升,因爲陡峭/開始振盪而不是急劇跳躍。
    • 當有問題的窗口正在加載相當大的(內存方式)iframe內容時,此問題最爲明顯。我用於所有測試目的的窗口在其iframe中加載了一個580 kb頁面(未緩存)。
  2. 奇怪的是,預期的垃圾收集確實發生,當

    • 瀏覽器隨後被最小化
    • 另一個選項卡在同一個瀏覽器窗口中打開
    • 一內存時間軸正在開發人員工具中記錄。 (喜劇選項)
    • 此行爲是否表示解決#1的任何可能方法?
+5

非常有趣的問題,並很好的解釋。我不確定究竟是什麼罪魁禍首,雖然我會警告你有可能不會有解決辦法。或者如果有一個,不是一個容易的。 Google對編程採取了非常懶惰的方式。雖然Chrome似乎加載速度最快,並且使用的是每個主要瀏覽器的最小內存,但它充斥着我在Firefox或Opera中不會想到的錯誤。與Android和iOS相同。 – stevendesu 2010-10-31 17:16:06

+0

我在Google的Chrome網站管理員幫助論壇上發佈了一個非常詳細/冗長的此問題版本,但沒有得到答覆,所以這次我決定讓它更具針對性!我同意這看起來像一個錯誤(或者Chrome如何確定哪些對象被垃圾收集)。就好像Chrome最小化時發生的垃圾收集更加劇烈,我的窗口對象也許並不完全是Chrome的標準。感謝您的評論! – freenatec 2010-10-31 17:35:06

+4

@steven_desu:Google不僅對編程採取懶惰的方式,而且對於用戶提出的任何投訴或問題似乎都表現出冷漠的態度。 – 2010-10-31 19:27:21

回答

6

我不知道這是在Windows測試,但如果記住所以記住,只要你在窗口最小化窗口的所有數據移動到頁面文件。當再次打開窗口時,除非程序嘗試訪問它們,否則它不會移回內存塊,因此任何垃圾都會留在頁面文件中,但實際上並未收集。

如果你想使它自動化,它不僅會減慢程序速度,它也不會幫助解決任何內存問題。

請參閱以下網址有點更多信息

https://micksmix.wordpress.com/2010/01/08/why-does-task-manager-show-an-applications-memory-usage-drop-after-minimizing-it-to-the-the-taskbar/

+0

我相信,Intranet上將使用該站點的所有機器都運行Windows XP。我沒有考慮過這個頁面文件的問題,儘管自動化/將Chrome簡化爲最小化狀態(不管怎樣,無論效果如何)都是一個長遠的概念......理想情況下,我會找到一些方法來更改我的JavaScript代碼,以便Chrome能夠按照慣例識別垃圾收集的對象。 – freenatec 2010-10-31 20:29:04

+1

您是否嘗試將變量/對象設置爲null,一旦你完成它們? – William 2010-10-31 20:40:37

+0

就我掌握處理窗口關閉行爲的庫函數而言,它似乎在窗口關閉時將所有相關對象設置爲null。加載到窗口中的內容(在iframe中)是我自己的代碼,它有點混亂,可能會導致泄漏......但是,我應該注意到,當窗口關閉時,Firefox顯然會釋放內存(調到3-5 MB大約5秒鐘)。另一方面,相關Chrome進程的內存使用情況在關閉窗口時保持靜態,並且使其減少的唯一因素是使瀏覽器最小化。 – freenatec 2010-10-31 20:52:13

3

更新
以下更改MochaUI closingJobs功能是改善了我以前在這裏公佈。主要變化是現在iframe的onunload事件是通過更改src屬性手動調用的,而不是在windowEl.destroy方法從DOM中移除iframe時被觸發。 (從here得到了這個想法)。

如果您想使用此代碼,只需刪除現有的closingJobs函數並複製粘貼此代碼的位置。它應該兼容0.9.7和0.9.8 MochaUI,以及Mootools 1.2.4或1.3。


closingJobs: function(windowEl){   
    windowEl.setStyle('visibility', 'hidden'); 
    var instances = MUI.Windows.instances; 
    var instance_id = windowEl.id 
    var cleanup_delay = 50; 

    /* 
    Reset canvases with width/height = 0. 
    This pretty reliably frees a few hundred Kb of 
    memory in chrome. 
    */   
    instances[instance_id].canvasControlsEl.width = 0; 
    instances[instance_id].canvasControlsEl.height = 0; 
    instances[instance_id].canvasEl.width = 0; 
    instances[instance_id].canvasEl.height = 0;   

    if(instances[instance_id].options.loadMethod == 'iframe') 
    { 
/* 
The following line determines how long to delay the execution of 
the windowEl.destroy function. The line below gives 10 milliseconds 
per DOM element in the iframe's document. 
You could probably do just as well with a hard-coded value. 
*/   
     cleanup_delay = instances[instance_id].iframeEl.contentDocument.getElementsByTagName("*").length * 10;    

/* 
Set the Browser property in the iframe's window to Internet Explorer. 
This causes Mootools to run its purge function, which iterates over 
all the iframe document's DOM elements, removing events/attributes etc. 
Assuming you have mootools included in the iframe content.  
*/ 
     if(instances[instance_id].iframeEl.contentDocument.defaultView.MooTools) 
     {   
      if(instances[instance_id].iframeEl.contentDocument.defaultView.MooTools.version.contains("1.3"))     
       instances[instance_id].iframeEl.contentDocument.defaultView.Browser.ie = true; 
      else   
       instances[instance_id].iframeEl.contentDocument.defaultView.Browser.Engine.trident = true; 
     }     

     instances[instance_id].iframeEl.src = "javascript:false"; 
    }  

    MUI.cleanWindow.delay(cleanup_delay, null, windowEl);  
}, 

cleanWindow: function(windowEl) 
{        
    var instances = MUI.Windows.instances; 
    var instance_id = windowEl.id 
    if (Browser.ie){ 
     windowEl.dispose(); 
    } 
    else { 
     windowEl.destroy(); 
    }  
    instances[instance_id].fireEvent('onCloseComplete'); 

/* 
Changed - Only execute getWindowWithHighestZindex() and focusWindow() 
functions if there will actually be open windows after the 
current one closes. 
*/ 
    if (instances[instance_id].options.type != 'notification' && instances.__count__ > 1){ 
     var newFocus = MUI.getWindowWithHighestZindex(); 
     MUI.focusWindow(newFocus); 
    }  
    if (this.loadingWorkspace) this.windowUnload(); 
    if (MUI.Dock && $(MUI.options.dock) && instances[instance_id].options.type == 'window'){ 
     var currentButton = $(instances[instance_id].options.id + '_dockTab'); 
     if (currentButton != null){ 
      MUI.Dock.dockSortables.removeItems(currentButton).destroy(); 
      currentButton = null; //Is this necessary? 
     }   
     MUI.Desktop.setDesktopSize(); 
    } 

    //Changed - moved this to the end of the function. 
    delete instances[instance_id]; 
} 
+1

。 mootools 1.3有一些簡化的element.prototype.destroy,所以它看起來像這樣:http://github.com/mootools/mootools-core/blob/master/Source/Element/Element.js#L677 vs舊的http:/ /github.com/mootools/mootools-core/blob/1.2x/Source/Element/Element.js#L579進入上面奇怪的'clean()'函數。 – 2010-11-02 14:22:56

+0

1.2.4。我看到1.3版本發生了相同的事情(使用0.9.7 MochaUI版本,就是這樣)。在我的測試中,我確實使用了兼容性層,但我不確定這是否是一個因素。我上面提出的修正對Chrome的內存行爲有影響,1.3.4和1.2.4一樣。然而,所有這一切都可能發生變化:根據你的第一條評論,我在mocha ui的github上多了一些內容 - 我完全沒有意識到0.9.8分支最近有很多活動!感謝您將此引起我的注意。 – freenatec 2010-11-02 15:14:41

+0

不用擔心!老mochaui一直......難以合作。由於我必須實施大量修復程序,因此我仍然支持自己的分支,現在使用0.9.8或1.0將幾乎不可能!好吧! – 2010-11-02 15:41:46