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
  • The venu2/venu2s has much more memory for widgets than most other devices (763k).  Also, the v2/v2s is the only device that has the graphics pool, so things like bitmaps and custom fonts are not in the apps memory space, but in the graphics pool.  Same with makeImageRequest data.

    On a real device, widgets time out and close in 1-2 minutes, where in the sim, they will run forever.  Have you tried to use "view memory" in the sim to see what's going on? 

Comment
  • The venu2/venu2s has much more memory for widgets than most other devices (763k).  Also, the v2/v2s is the only device that has the graphics pool, so things like bitmaps and custom fonts are not in the apps memory space, but in the graphics pool.  Same with makeImageRequest data.

    On a real device, widgets time out and close in 1-2 minutes, where in the sim, they will run forever.  Have you tried to use "view memory" in the sim to see what's going on? 

Children
  • Is there any update on the status of the ticket for this?

  • 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 {

        }

    }