Where is the leak in HTTPClient

58 views Asked by At

I have been at this problem for days now and still can't find out what the problem must be.

The HTTPClient is not being cleaned up properly and thus the apps memory is exploding when looping over say 100 images to download.

I am testing in a simple alloy template created by using appc new -t titanium.

only an index view is opened with one button to start the download loop

my index file looks like the following:

var max = 100
var i = 0

var c = Ti.Network.createHTTPClient();
c.onerror = function () {
  c = null;
}
c.onload = function () {
  saveFile(this.responseData)
  console.log("done get")
  i++
  getfiles()
}

function getfiles () {

  if (i < max) {

    try {
      c.open('GET', "https://cdn.fossilswitzerland.ch/large0/FS4931.jpg");
      c.send();
    } catch (e) {

    }
  } else {
    c = null
    console.log("finished")
  }
}

function saveFile (response) {

  console.log("STORING")

  var f = Ti.Filesystem.getFile(Ti.Filesystem.applicationDataDirectory, 'FS4931.jpg');
  f.write(response);

  if (f.exists() === false) {
    console.log("NOT STORED")
  } else {
    console.log("STORED")
  }

  f = null;

}


$.index.open();

Initially after the app has booted memory is at ca. 30mb So far so good After clicking get images button on the index page, memory goes up to ca. 62mb Then after a while goes down to ca. 50mb which leaves 20mb unaccounted for

I am using: Xcode 10.3 Ti SDK Version 8.1.1.GA Simulator: iPad Pro (2nd generation) on 12.4

enter image description here

When changing max to 1000, memory soars to around 322mb and doesn't seem to decrease at any more.

This is a really big problem when looping through and downloading say 2000 images because the app just crashes at some point

Thank you for any help

1

There are 1 answers

0
miga On

I've changed the code a bit (for-loop, use the file property, don't re-use the httpclient (check the documentation), classic code so it is quicker to test):

var w = Ti.UI.createWindow();
var b = Ti.UI.createButton({
    title: "download"
});
w.add(b);

function onError(e) {
    console.log("error", e);
}

function onLoad(e) {
    console.log("done get")
}

function getfiles(e) {
    for (var i = 0; i < 100; ++i) {
        var c = Ti.Network.createHTTPClient({
            onerror: onError,
            onload: onLoad
        });
        c.open('GET', "https://cdn.fossilswitzerland.ch/large0/FS4931.jpg");
        var fname = Ti.Filesystem.applicationSupportDirectory + "/" + (new Date().getTime()) + ".jpg";
        console.log("Download to", fname);
        c.file = fname;
        c.send();
        c = null;
        fname = null;
    }
}
b.addEventListener("click", getfiles);
w.open();

I get a little overhead when it is releasing memory (around 5mb). You could create a JIRA ticket (https://jira.appcelerator.org/) so they can check it.