Soumya
Soumya

Reputation: 1420

Alloy createController is not released from memory

Recently I have been doing some memory analysis on one of my application. The application is made for Android platform. For two of the screens, I am observing that there is a leak.

No validate, I removed all of my code and kept only $.screenName.open() call on both the controllers and they way of calling them is:

Alloy.createController(screenToLaunch, payloadJson);

Inside the respective controllers, the open() call was present. I use DDMS and do a heap analysis.

Before opening Controller A, I pressed the cause GC several time to get a stable allocated reading. Once done I launch Controller A and press the back button to close it. Now when I click on cause GC several times, there is a difference of 60KB, everytime.

I am not storing the createController reference in any global variable. Any idea as to why it is behaving in such manner?

Updated: HPROF Difference

Above is the HPROF difference between opening and closing of the controller. I am not using any DB calls, yet I see there are many DB related calls being made. I think it might be that the framework is using those calls for its internal functioning.

Upvotes: 1

Views: 452

Answers (2)

rjcpereira
rjcpereira

Reputation: 953

This is my cleanup method for all controllers and widgets:

someview.js

var args = arguments[0] || {},
    data = {};

data.button = Alloy.createController('button',{
    title:'button'
}).getView();

 $.view.cleanup = function() {

    $.destroy();

    $.off();

    data.button.cleanup();

    $ = data = args = null;
};

button.js

var args = arguments[0] || {},
    data = {};

data.click = function() { ... };

$.view.addEventListener('click',data.click);

$.view.cleanup  = function() {

    $.destroy();

    $.off();

    $.view.removeEventListener('click',data.click);

    $ = data = args = null;
};

I've created a global function, to call the cleanup method and remove it's content on every children of the controllers:

UPDATE

added delete operator and try statement

exports.unset = function(view) {

    if(view) {

        if(view.children && view.children.length) {

            for(var i in view.children) try { util.unset(view.children[i]);
            } catch(e) {}

            view.removeAllChildren();
        }

        if(view.views && view.views.length) for(var i = view.views.length; i > 0; i--) if(view.views[i-1]) {

            if(view.removeView) view.removeView(i-1);

            try { util.unset(view.views[i-1]);
            } catch(e) {}
        }

        if(view.cleanup) try { view.cleanup();
        } catch(e) {}

        view = null;

        delete view;
    }
};

Upvotes: 0

Jagu
Jagu

Reputation: 762

I'm using this architecture for controllers (UI.Windows) and works very well.

  • Open window : Alloy.createController('name_controller').getView().open();

Cleaning up Alloy controllers

Upvotes: 0

Related Questions