Reputation: 571
Background: I'm currently working on an intranet site that makes use of the MochaUI library (working from the virtual desktop demo). I'm using Mootools 1.2.4 and MochaUI 0.9.7. The windows that are opened in my "virtual desktop" implementation load their content via iframes. Some of the loaded pages are pretty hefty in terms of css and scripting, so it's important that Window objects are adequately garbage collected when the user closes a window. This is ostensibly taken care of by the library (it does do a fair job when using Firefox).
Update The originally posted question had become overly long from subsequent edits/updates. The title wasn't accurate anymore, so I changed that as well. Also, see my answer below for a partial solution.
Here are the essential points:
Chrome goofs up like so:
Strangely enough, the expected garbage collection does take place, when
Upvotes: 27
Views: 3925
Reputation: 3464
I'm not sure if this was tested in Windows, but if so keep in mind that whenever you minimize a window in windows it moves all data to the pagefile. When opening the window again it won't move the memory blocks back unless the program tries to access them, and thus any garbage stays in the pagefile but isn't actually collected.
If you'd automate it, it would not only slow the program down it would also not help with any memory issues.
see the following url for a bit more info
Upvotes: 6
Reputation: 571
Update
The following changes to the MochaUI closingJobs function are a big improvement over what I previously posted here. The main change is now the iframe's onunload event is manually called by changing the src property, instead of being fired when the windowEl.destroy method removes the iframe from the DOM. (got the idea from here).
If you want to use this code, just delete the existing closingJobs function and copy paste this code in its place. It should work with both 0.9.7 and 0.9.8 MochaUI, and either Mootools 1.2.4 or 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];
}
Upvotes: 3