Memory leak in setProperty()

Former Member
Former Member
I believe there is a memory leak in setProperty(). I think the easiest way to provide an example is for you to edit the primates sample. Update the following functions to the following code. To stop the memory leak behavior you can just comment out the setProperty.. line.
I also had other memory leaks that I have resolved. Of note is that they did not show in the simulator, but occur on my device (920XT). I think the simulator should be made to recognize these problems.

Forgot to mention. To see the leak you must run on your device, and scroll through the pages. Each time you reenter a page the used memory will be greater.

Primates.mc
function onStart() {
var key = 0;
var value = getProperty(key);
if(null != value) {
deleteProperty(key);
value = 0;
}
setProperty(key,value);
}

PrimatesView.mc
function onUpdate(dc)
{
dc.setColor( Gfx.COLOR_TRANSPARENT, Gfx.COLOR_BLACK );
dc.clear();

dc.setColor(Gfx.COLOR_WHITE, Gfx.COLOR_BLACK);
dc.fillRectangle(0, 0, dc.getWidth(), dc.getHeight());

dc.setColor( color, Gfx.COLOR_TRANSPARENT );
dc.drawText(5, 5, Gfx.FONT_SMALL, primates[index], Gfx.TEXT_JUSTIFY_LEFT);

dc.drawBitmap(25, 30, bitmap);

indicator.draw(dc, index);

dc.setColor( Gfx.COLOR_BLACK, Gfx.COLOR_BLACK );
var _text = "Usedmem: " + System.getSystemStats().usedMemory;
dc.fillRectangle(0,0,218,22);
dc.setColor(Gfx.COLOR_WHITE,Gfx.COLOR_BLACK);
dc.drawText(0, 0, Gfx.FONT_TINY, _text, Gfx.TEXT_JUSTIFY_LEFT);
}

PrimatesDelegate.mc // Handlers for those without touchscreen
function onKey(event) {
var key = event.getKey();

if(Ui.KEY_UP == key) {
onPreviousPage();
}
else if(Ui.KEY_DOWN == key) {
onNextPage();
}
else if(Ui.KEY_ESC == key) {
Ui.popView(Ui.SLIDE_IMMEDIATE);
}
return true;
}
  • Former Member
    Former Member over 10 years ago
    As an aside. How do you make the images show in the a post. Last time I hacked the code to make one appear I got booted, no that wasn't this time I got booted, that was the time before last. The first time was when I tried to post a spreadsheet that translated all the colors to swatch, dec, hex, constant. Sigh.
  • Taking it one step further, deleting an existing key and resaving it will also cause the problem.

    The following test case does not demonstrate the problem in the simulator or on a 920xt (3.20 firmware). It deletes and recreates the property every second, but does not show any memory growth after the first call (I see it sit at 7862 bytes). What am I missing?

    using Toybox.Application as App;
    using Toybox.Graphics as Gfx;
    using Toybox.Timer as Timer;
    using Toybox.System as Sys;
    using Toybox.WatchUi as Ui;

    class Test extends Ui.View {

    hidden var _timer;

    function initialize() {
    _timer = new Timer.Timer();
    }

    function onShow() {
    _timer.start(self.method(:onTimer), 1000, true);
    }

    function onHide() {
    _timer.stop();
    }

    function onTimer() {
    var key = 0;

    var value = App.getApp().getProperty(key);
    if(null != value) {
    App.getApp().deleteProperty(key);
    value = 0;
    }
    App.getApp().setProperty(key,value);

    Ui.requestUpdate();
    }

    //! Update the view
    function onUpdate(dc) {
    dc.setColor(Gfx.COLOR_BLACK, Gfx.COLOR_BLACK);
    dc.clear();

    var cx = dc.getWidth() / 2;
    var cy = dc.getHeight() / 2;

    dc.setColor(Gfx.COLOR_WHITE, Gfx.COLOR_TRANSPARENT);

    var s = Sys.getSystemStats();
    dc.drawText(cx, cy, Gfx.FONT_LARGE, s.usedMemory.toString(),
    Gfx.TEXT_JUSTIFY_CENTER | Gfx.TEXT_JUSTIFY_VCENTER);

    dc.drawText(cx, cy - 25, Gfx.FONT_TINY, Time.now().value().toString(),
    Gfx.TEXT_JUSTIFY_CENTER | Gfx.TEXT_JUSTIFY_VCENTER);
    }
    }


    And since presently you must delete a key to save an array, there is effectively no way to save an array without the problem arising, other than on app exit.

    I believe you can easily force a resave by moving the address of the array...

    // to ensure that 'values' is properly saved into the object store
    if (values != null) {
    var new_values = new [ values.size() ];

    for (var i = 0; i < values.size(); ++i) {
    new_values= values;
    }

    values = new_values;
    }

    setProperty("Values", new_values);
    [/code]

    How do you make the images show in the a post.

    Insert an image into the post, then choose From Computer > Select Files > Upload Files. That will attach a file to your post. Then click Go Advanced, find the link in your post, then right-click the line and copy the URL for the image. Then insert an image again, this time using the From URL option and being sure not to select the Retrieve File... option.
  • Former Member
    Former Member over 10 years ago
    The following test case does not demonstrate the problem in the simulator or on a 920xt (3.20 firmware). It deletes and recreates the property every second, but does not show any memory growth after the first call (I see it sit at 7862 bytes). What am I missing?
    Are you leaving the page and coming back to it? Maybe if you call setProperty a second time on the same key the problem goes away? Try placing the code in the onShow like I demonstrated, delete the storage file, run the app on a device (simulator does not show the problem), scroll in & out of a page a few times.

    I believe you can easily force a resave by moving the address of the array...
    But to move it I need to create a new key.... back to square one, or have I missed something? Although now that you mention that, I believe I could possibly resize the array, which would mean it will update. Yes I could keep track of 30 arrays with bit flags in a single int, and toggle a resize, but it's all getting rather messy.

    Insert an image into the post, then choose From Computer > Select Files > Upload Files. That will attach a file to your post. Then click Go Advanced, find the link in your post, then right-click the line and copy the URL for the image. Then insert an image again, this time using the From URL option and being sure not to select the Retrieve File... option.
    Excellent. Thank you.
  • Former Member
    Former Member over 10 years ago
    Snapped. I didn't read your code. The problem does not show while you remain in the same view, that is why I used the primates sample to highlight my point.
  • Finally... I can reproduce a memory leak with your above snippet combined with page transitions. I'll argue that the leak is not in setProperty(), but in one of the page transition functions, most likely switchToView(), but one of the ConnectIQ guys will probably sort that out when filing the bug.

    As for your other question, you don't need to write a ton of code to work around the serializing arrays problem. Just write a function that make s a copy of an array, and use it immediately after reading the array from storage or immediately before writing the array to storage. You just need to do it once for each array, so this code...

    setProperty("Array1", array1);


    becomes this...

    setProperty("Array1", duplicate_array(array1));


    Travis
  • Former Member
    Former Member over 10 years ago
    Actually I don't even use the old array, I just assumed I still needed to delete the key, so it turns out that is not a problem. Oddly however, despite filling all the keys so there are no new keys being created, the problem still exists in my app. I will write the problem out.
  • The setProperty() memory leak has been fixed and was made available in the 1.1.1 SDK release.