Details

      Description

      I noticed lots of HttpClientProxy leaks in our Android application. We double checked our code, ran some tests, profiled the same code base on iOS (it was fine on iOS). Eventually we realized the the HTTPClient object is leaking only when there are concurrent xhr requests.

      Test 1 (Leaks)
      ------------------

      I built a test case and profiled it to confirm our conclusion. In test one, the app will send 20 concurrent HTTP requests. When profiled, it will show that all the HTTPClientProxy objects were leaked, even after invoking GC multiple times.

      "20 instances of "ti.modules.titanium.network.HTTPClientProxy", loaded by "dalvik.system.PathClassLoader @ 0xb1083270" occupy 5,327,960 (28.38%) bytes."

      Test 2 (Doesn't Leak)
      ----------------------------

      While with test 2, the requests are queued and sent one at a time (100ms delay between every response and next request). The profile result showed that none of the HTTPClientProxy objects were leaked.
      I read numerous posts on this forum and most of them were old (from 1.8 days). I'm running my tests on version 3.2.3. Android 4.3.2.

      Test code below:

      function xhrRequest(callback) {
      var xhr = Ti.Network.createHTTPClient({
      timeout : 5000,
      cache : false,
      onload : function(e) {
      if (callback)

      { callback(); }
      }
      });

      xhr.open('POST', 'https://www.yahoo.com/');
      xhr.send();
      }

      function xhrRequestTest1(tests, callback) {
      var completed = 0;
      for (var i=0;i<tests;i++) {
      xhrRequest(function() {
      console.log('Test 1 #' + completed + ' completed');
      completed += 1;
      if (completed == tests) { callback(); }

      });
      }
      }

      function xhrRequestTest2(tests, callback) {
      if (tests == 0)

      { callback(); return; }

      xhrRequest(function() {
      console.log('Test 2 #' + tests + ' completed');
      setTimeout(function()

      { xhrRequestTest2(tests-1, callback); }

      , 100);
      });

      }

      var window = Ti.UI.createWindow(

      { layout : 'vertical' }

      );

      var button1 = Ti.UI.createButton(

      { title : 'Test #1: Concurrent XHR requests' }

      );

      button1.addEventListener('click', function() {
      xhrRequestTest1(20, function()

      { alert('Test 1 completed. Invoke GC and test for leaks'); }

      );
      });

      var button2 = Ti.UI.createButton(

      { title : 'Test #2: Queued XHR requests' }

      );

      button2.addEventListener('click', function() {
      xhrRequestTest2(20, function()

      { alert('Test 2 completed. Invoke GC and test for leaks'); }

      );
      });

      window.add(button1);
      window.add(button2);

      window.open();

        Attachments

          Activity

            People

            • Assignee:
              mpmiranda Mauro Parra-Miranda
              Reporter:
              ekhoury Elie Khoury
            • Watchers:
              4 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved:

                Git Source Code