We are having massive issues with memory management on Android. The issue appears to arise when we dispose of views that have images in them. It simply looks like the garbage collector is never getting rid of the image data.
Things we have tried:
No global variables
Completely closing and deallocating windows when switching pages (closing and deallocating windows doesn't seem to clear ANY memory or any of the views inside those windows)
Switching from a multi-window app to a single window app that swaps out views instead of switches windows (helped, since we don't have to deal with all of the extra memory from closed/nulled windows)
Recursively deleting / nulling child elements when removing a view from the window (helped a lot, but doesn't return any memory from images in those views/children)
When removing a child element, manually setting its image and backgroundImage attributes to null (didn't do anything)
Switching everything to factory methods (helped a bit)
Creating a huge fake array to force the OS to call garbage collection (helped a lot)
After all of that work, our current issue is still just that no memory gets returned that was allocated for images. We have tested this simply by removing only the images from the app, which instantly solves our memory problem.
Basically we start at 55 Mb worth of RAM usage and the app just constantly grows from there, regardless of how much we close, remove and null out views.
DDMS shows the heap never goes above 40 to 45 megs, but the android task manager shows memory from anywhere around 55m to 150m before crashing. We also have largeHeap set to true.
Below is our recursive methods to clear the views. Is there something that we are doing wrong or is there another way to clear the memory of non used objects?
RecursiveClearChildViews: function(targetView, parentWindow, currentLevel){ this.internalRecursiveClearChildViews(targetView, parentWindow, currentLevel); var crapholdingarray = []; for(var i = 0; i < 20000; i++) { crapholdingarray.push("SOMESTUFFGOESHERETOFILLUPMEMORY,YO"); } crapholdingarray = null; }, internalRecursiveClearChildViews: function(targetView, parentWindow, currentLevel){ currentLevel = currentLevel || 0; if (currentLevel == 1) { targetView.hide(); if (parentWindow) { parentWindow.remove(targetView); } } var children = targetView.children.slice(0); for (var i = 0; i < children.length; ++i) { var thisChild = children[i]; if (thisChild.children.length > 0) { this.internalRecursiveClearChildViews(thisChild, parentWindow, currentLevel+1); } if(thisChild.backgroundImage){ thisChild.backgroundImage = null; Ti.API.info( 'Deleted backgroundImage' ); } if(thisChild.image){ thisChild.image = null; Ti.API.info( 'Deleted image' ); } targetView.remove(thisChild); thisChild = null; } }We are using:
Titanium SDK 3.2.2.GA
Targeting Android and iPad (no memory issues with ios)
Testing on Android devices not emulators
Thanks!