How would you resolve the following memory leak?
I am trouble shooting memory leaks in an iOS app Ti SDK 6.2 without much success.
When opening and closing windows the xcode Instruments Allocations tool shows a number of TiUIxxxxProxy objects remain in memory.
To test/debug the issue I created a super simple classic appcelerator app (code shown below). Using the code below I open window1 from app.js, then open window2 from a button on window1.
You can see in the attached xcode Instruments Allocations images that after window2 is closed the proxy objects remain (window, table, etc). Worse yet, opening and closing window2 multiple times keeps adding additional proxy objects that use memory.
App.js
require('Window1').CreateWindow().open();
Window1.js
exports.CreateWindow = function(){
try{
var window1 = Ti.UI.createWindow({
title:'Window 1',backgroundColor:'yellow',
});
var button1 = Ti.UI.createButton({
top:'50dp', center:'50%',
borderWidth:'1dp',borderColor:'black',
title:' Open Window 2 '
});
window1.add(button1);
button1.addEventListener('click', function() {
var win2 = require('Window2').CreateWindow();
win2.open();
});
return window1;
}
catch(e){
alert('Window 1 Error: ' + e);
}
};
Window2.js
exports.CreateWindow = function(){
try{
var window2 = Ti.UI.createWindow({
title:'Window 2',layout:'vertical'
,top:'200dp',bottom:'200dp',width:'80%'
,backgroundColor:'orange'
});
var button2 = Ti.UI.createButton({
top:'50dp', center:'50%',
borderWidth:'1dp',borderColor:'black',
title:' Close Window 2 '
});
window2.add(button2);
button2.addEventListener('click', function() {
window2.close();
});
// create a table row
var tvRow1 = Ti.UI.createTableViewRow({ });
//create a label to display location name
var labelRow1 = Ti.UI.createLabel({
color:'#000000',
left:'15dp',
top:'10dp',
text:'Label in row 1'
});
tvRow1.add(labelRow1);
// define table section for this group of rows
var tableViewSection1 = Ti.UI.createTableViewSection({ });
// push row into table view section
tableViewSection1.add(tvRow1);
//create array to store table sections
var arrayTableSections = [];
//add table section to array
arrayTableSections.push(tableViewSection1);
// create table
var table2 = Titanium.UI.createTableView({
data: arrayTableSections,
top:'50dp',
left:'50dp',
right:'50dp',
height:Ti.UI.SIZE,
backgroundColor:'#ffffff' ,
borderColor:'black',borderWidth:'1dp'
});
// add table to window
window2.add(table2);
return window2;
}
catch(e){
alert('Window 2 Error: ' + e);
}
};
The specific problem you're having is that you're manually creating elements and not cleaning up. So, on the close of Window2 you should be removing all elements from their parents, and ultimately from Window2 so:
then
and most importantly:
Once done, ensure you have a removeEvenlistener in close to remove the event handler too.
Finally, close the window and nullify it.
One last thing, don't create a window2 pointer in window1 if you're not going to need it later so:
require("window2").createWindow().open();
is better than:
var window2 = require("window2").createWindow();
window2.open();
Doing that I was able to open window2 8+ times, and it all cleaned up afterwards.