Ticket Created
over 3 years ago

CIQQA-637

repeated makeImageRequest calls cause memory leak

I'm running a widget that makes repeated makeImageRequest calls and am noticing memory consumption go

up by 0.1 to 0.2kB for each call.  Looks like a memory leak. I'm using Connect IQ SDK 4.0.3 and users are reporting out of memory crashes.

I tried the widget app with every watch model in the simulator and the problem occurs on every model except Venu2 and Venu2s.  

Incidentally the widget app under Venu2 and Venu2s takes extremely little memory to run compared to other models.  I'm not sure why.

Parents
  • OK I ran a test looking at the memory stats.  After a few imageRequests, Memory Usage went up by about 4k, Object usage, and peak objects goes up by 1 for each imageRequest.  But examining the detailed categories of memory, I haven't found any one of them change in size.

Comment
  • OK I ran a test looking at the memory stats.  After a few imageRequests, Memory Usage went up by about 4k, Object usage, and peak objects goes up by 1 for each imageRequest.  But examining the detailed categories of memory, I haven't found any one of them change in size.

Children
  • You can also set a flag in triggerRequest, clear it in reposonceCallback, and in timerRequest, don't call triggerRequest if that flag is set.

    You are assuming that the request will always complete  in less than 1 sec, and that might not always be a valid assumption.

  • You are requesting an image every second without checking if there is a request active.  Try moving  triggerRequest() out of timerCallback() and instead do it in responseCallback, so you can't have multiple requests at the same time.

  • I still don't see the problem.  I made a simple test project to demonstrate the problem.  Just create a default Widget project and paste this code in the view, and run.

    import Toybox.Graphics;

    import Toybox.WatchUi;

    import Toybox.Timer;

    class PhotoWidView extends WatchUi.View {

    var image;

        function initialize() {

            View.initialize();

        }

        function onShow() as Void {

        triggerRequest();

        }

        

        function onLayout(dc as Dc) as Void {

        var myTimer = new Timer.Timer();

        myTimer.start(method(:timerCallback), 1000, true);

        }

        

    function timerCallback() {

        triggerRequest();

    WatchUi.requestUpdate();

    }

        function responseCallback(responseCode, data) {

            responseCode = responseCode;

            image=null;

            if (responseCode == 200) {

                image = data;

            } 

        }

        

    function triggerRequest() {

            var url = "">encrypted-tbn0.gstatic.com/images;

            var options =  {          

                 :palette => [0x00000,

    0x555555,

    0xaaaaaa,

    0xaa0000,

            0xff5500,

            0x55aa00,

            0x5500ff,

            0xaa5500,

            0xffffff],

              :maxWidth => 240,        // set the max width

                :maxHeight => 240,        // set the max height

                :dithering => Communications.IMAGE_DITHERING_NONE   // set the dithering

            };

            Communications.makeImageRequest(url, null, options, method(:responseCallback));

        }    

        

        function onUpdate(dc as Dc) as Void {

            View.onUpdate(dc);

            if (image!=null) {

            dc.drawBitmap(0,0,image);

            }

        }

        function onHide() as Void {

        }

    }

  • If objects and peak objects keep increasing, that's the first place I'd look.