Mark Herscher
Mark Herscher

Reputation: 1810

Memory leaks in Appcelerator Android HTTP?

I am running into what looks like a memory leak on Android using Appcelerator. I am making an HTTP GET call repeatedly until all data is loaded. This call happens about 50 times, for a total of roughly 40 MB of JSON. I am seeing the memory usage spike dramatically if this is executed. If I execute these GETs the heap size (as reported by Android Device Monitor, the preferred method to check memory according to the official Appcelerator docs) gets up to ~240 MB and stays there for as long as the app runs. If I do not execute these GETs, it only uses about 50 MB. I don't think this is a false heap reading either, because if I execute the GETs again (from page 1) I run out of memory.

I have looked through the code and cannot find any obvious leaks, such as storing all results in a global variable or something. Are the HTTP responses being cached somewhere?

Here is my code, for reference. syncThings(1, 20) (sanitized name :) ) gets called during startup. It in turn calls a helper function syncDocuments(). Here are the two functions. Don't worry about launchMainWindow() unless you think it could be relevant, but assume it does no cleanup.

function syncThings(page, itemsPerPage) {
    var url = "the_url";

    console.log("Getting page " + page);
    syncDocuments(url,
        function(response) {
            if (response.totalDocumentsInQuery == itemsPerPage) {
                // More pages to get
                setTimeout(function() {
                        syncThings(page + 1, itemsPerPage);
                    }, 1);
            } else {
                // This was the last page
                launchMainWindow();
            }
        },
        function(e) {
            Ti.API.error('Default error callback called for syncThings;', e);
            dispatcher.trigger('app:update:stop');
        });
}


function syncDocuments(url, successCallback, errorCallback) {
    new HTTPRequest({
        url: url,
        method: 'GET',
        headers: {
            'Content-Type': 'application/json'
        },
        timeout: 30000,
        success: function (response) {
            Ti.API.info('Success callback called for ' + url);
            successCallback(response);
        },
        error: function (error) {
            errorCallback(error);
        }
    }).send();
}

Any ideas? Am I doing something wrong here?

Edit: I am using Titanium SDK 6.0.1.GA. This happens on all Android versions.

Upvotes: 0

Views: 262

Answers (1)

miga
miga

Reputation: 4055

Try using the file-property of the HTTPClient: http://docs.appcelerator.com/platform/latest/#!/api/Titanium.Network.HTTPClient-property-file

otherwise the file will be loaded into memory.

There will be a memory leak fix in 6.1.0: https://github.com/appcelerator/titanium_mobile/pull/8818 that might fix something too.

Upvotes: 0

Related Questions