Memory leak in org.apache.cordova.geolocation 0.3.12?

189 views
Skip to first unread message

Rob Willett

unread,
Mar 6, 2015, 10:07:30 AM3/6/15
to phon...@googlegroups.com
Hi,

I've been trying to track down where my memory is going in my App. Using Xcode I could see that there was a slight but steady increase in memory usage over 10-15 mins. e.g. I would start at 50MB and 10 mins later I would have used up 124MB.




After working through all the obvious candidates (my code), I finally came across 

navigator.geolocation.getCurrentPosition(onGPSSuccess , onGPSFailure);

    function onGPSSuccess(position)
    {
        var debugonGPSSuccess = 0;

if (debugonGPSSuccess)
            ConsoleLog("Poller: Acquired GPS returning long,lat " + position.coords.longitude + "," + position.coords.latitude);

        currentGPS.Longitude = position.coords.longitude;
        currentGPS.Latitude = position.coords.latitude;

GPSsuccess = true;
    }

    function onGPSFailure(error)
    {
        if (error)
        {
            ConsoleLog('onGPSFailure: code: '    + error.code    + '\n' +
               'message: ' + error.message + '\n');
        }

        if (debugGPS)
            ConsoleLog("Poller: Can't acquire GPS so setting GPS to default " + JSON.stringify(defaultGPS));

        currentGPS = defaultGPS;
    }


If I commented this line out, the memory usage stays flat. The logic in onGPSSuccess and onGPSFailure simply sets a variable capturing the position, if I emulate a successful GPS function by removing navigator.geolocation.getCurrentPosition(onGPSSuccess , onGPSFailure)  then the memory stays more or less flat as well. 




After playing about for most of the day, my only conclusion is that navigator.geolocation.getCurrentPosition is leaking memory every time its called. However since this is such a popular plugin I can't really believe I'm the first person to find this issue, but I can't see it anywhere else. 

I download and installed the previous version of the plugin 0.3.11 and it had the same problem. Common sense tells me that this can't true as lots of other people would have noticed by now.

The plugin is working and I have looked at the code but my skills aren't up to debugging it. 

So 

Q1 Is anybody else using org.apache.cordova.geolocation 0.3.X and are you having any issues?

Q2. I'm unclear how to raise an issue and report this. Any suggestions please?

Q3. Any really clever ideas that might help? I can't see anything in the doc that says use this a special way, its pretty simple and pretty easy. It certainly seems to work OK bar the memory leak.

Thanks,

Rob


Kerri Shotts

unread,
Mar 6, 2015, 3:34:09 PM3/6/15
to phon...@googlegroups.com
The cordova website (cordova.io) should have a link to the issue tracker where you can report a bug.

Some thoughts:

1) If you comment out the function body of onGPSSuccess, does the memory stay flat? 
2) Does the memory always increase? If you wait 20 minutes, is it still higher than at 10m? Does it ever decrease?

Rob Willett

unread,
Mar 6, 2015, 3:47:28 PM3/6/15
to phon...@googlegroups.com
Kerri,

Already commented out the function body of onGPSSucccess and had the same results. Memory still increases.

Memory keeps on increasing for at least 20 mins.

I have now managed to get the test case down to something very, very simple and reproducible. 

1. ionic start gpstest1 blank

2. cordova plugins rm org.apache.cordova.geolocation

3. This is now the app.js. I've just added the fps functions, a simple timer and the call to plugin.

angular.module('starter', ['ionic'])

.run(function($ionicPlatform) {
  $ionicPlatform.ready(function() {
    // Hide the accessory bar by default (remove this to show the accessory bar above the keyboard
    // for form inputs)
    if(window.cordova && window.cordova.plugins.Keyboard) {
      cordova.plugins.Keyboard.hideKeyboardAccessoryBar(true);
    }
    if(window.StatusBar) {
      StatusBar.styleDefault();
    }

      function onSuccess(position) {
 console.log("success!");
      };

      function onFailure(position) {
 console.log("Failure!");
      };

 setInterval(function() {
 navigator.geolocation.getCurrentPosition(onSuccess , onFailure);
 } , 1000);
  });
})

So I added onGPSSuccess, onFailure and the setInterval function. Thats it.

4. ionic build iOS

5. Run it on Xcode and watch the memory grow :)



This is only for 76 secs, but it keeps on growing. I'll leave it whilst I put the kids to bed (its 20:45 here in London) and see what its like in an hour or so.

I've tried to contact the plugin maintainers but no answer yet. Still unsure how what the right format is for raising an issue. As I can now create it using a simple test case, I tend to feel its not my code. 

Thanks,

Rob









--
-- You received this message because you are subscribed to the Google
Groups "phonegap" group.
To post to this group, send email to phon...@googlegroups.com
To unsubscribe from this group, send email to
phonegap+u...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/phonegap?hl=en?hl=en
 
For more info on PhoneGap or to download the code go to www.phonegap.com
---
You received this message because you are subscribed to the Google Groups "phonegap" group.
To unsubscribe from this group and stop receiving emails from it, send an email to phonegap+u...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Rob Willett

unread,
Mar 6, 2015, 3:48:31 PM3/6/15
to phon...@googlegroups.com
Whoops.... Pasted in the wrong line from the history

instead of 

2. cordova plugins rm org.apache.cordova.geolocation

It should say 


2. cordova plugins add org.apache.cordova.geolocation

its been a long day :)

Rob


Kerri Shotts

unread,
Mar 6, 2015, 3:52:03 PM3/6/15
to phon...@googlegroups.com
I was going to say... .;-)

Is this on a physical device or on the sim?

Also: have you tried using watchPosition instead? (It's entirely possible it has the same behavior, but it's a thought...)

For more options, visit this group at
http://groups.google.com/group/phonegap?hl=en?hl=en
 
For more info on PhoneGap or to download the code go to www.phonegap.com
---
You received this message because you are subscribed to the Google Groups "phonegap" group.
To unsubscribe from this group and stop receiving emails from it, send an email to phonegap+unsubscribe@googlegroups.com.

Kerri Shotts

unread,
Mar 6, 2015, 4:09:51 PM3/6/15
to phon...@googlegroups.com
I just tried (on the sim), and when using setTimeout as in your example, the memory does quickly grow. But if I switch to watchPosition, it improves greatly. Not to say that it entirely reduces memory growth, but it's a lot less, and may simply be a result of logging to the console.

Now, that may not mean anything on a physical device, but it's worth a try. 

Rob Willett

unread,
Mar 6, 2015, 5:31:23 PM3/6/15
to phon...@googlegroups.com
Kerri,

1. It’s both on the physical device and on the sim in Xcode. 

2. Just downloaded iOS 7.1 simulator and I get similar behaviour. Not left it for 90 mins but I can see that gently rise in memory usage. After 5 min memory has gone from 50MB to 63MB under iOS 7.1. 

3 I have looked at watchPosition already and thats showing similar (ish) behaviour. I haven’t drilled down deep and produced a simple use case though as I did before, but I will do that tomorrow. As you say it *may* be console logging. Does console logging actually increase memory usage? I googled for this but found nothing either way. If watchPositon has the same issue it tends to make me think that there’s a deep seated issue somewhere as deep down in geolocation they probably share a similar code base.

4. There’s nothing I can see on github about how to raise issues, apart from writing JSON objects to a push command, which is interesting and I could code it, but is rather reminiscent of debugging smtp through telnet and port 25.

5. The fact I can reproduce this with nothing more than a trivial cordova/ionic script says that there is a problem somewhere in the plugin. I did spend a lot of the day trying to get my head around Javascript memory profiling.  Not an area I’m familiar with, valgrind is my normal memory check system. I struggled to create the problem elsewhere, but since it has to run on iOS I’m left with the tools I have for iOS. Chrome isn’t going to be a big help here. It may work perfectly well in Chrome, but that doesn’t help me, apart from ppssibly indicating its an iOS issue.

6. I’ve left the the program running for 1 hour and 29 min, memory usage is now at 203MB, which in a black sort of way, kind of amusing.







For more options, visit this group at
http://groups.google.com/group/phonegap?hl=en?hl=en
 
For more info on PhoneGap or to download the code go to www.phonegap.com
---
You received this message because you are subscribed to the Google Groups "phonegap" group.
To unsubscribe from this group and stop receiving emails from it, send an email to phonegap+u...@googlegroups.com.

Kerri Shotts

unread,
Mar 7, 2015, 12:41:53 AM3/7/15
to phon...@googlegroups.com
The place to submit issues would be here: https://issues.apache.org/jira/browse/CB

So, I did a few experiments on my end, and it definitely appears that involving the console + remote inspection will definitely impact your memory results. This is expected, which means continual console logging is apt to grow memory by a small (but measurable) amount.

So I ran some tests without remote inspection connected, and here's what I saw (sim only):
* watchPosition: fairly stable; 11.7MB after 8 minutes. Slight trend upwards; guessing from logging. Something like 134 persistent objects present.
* getCurrentPosition + setInterval: out of control; 80MB after 6 minutes. 33,428 persistent objects present.

This may or may not bear out on a real device; it's bed time for me here, but so far it appears (for me, anyway) that watchPosition is the better way to go. Here's my watchPosition code:

        function start() {
          function onSuccess(position) {
            console.log("success!");
          };
          function onFailure(position) {
    console.log("Failure!");
          };
          options = {
            enableHighAccuracy: true,
            timeout          : 5000,
            maximumAge: 0
          };
          navigator.geolocation.watchPosition(onSuccess, onFailure, options);
        }
        document.addEventListener("deviceready", start, false);

Rob Willett

unread,
Mar 7, 2015, 5:36:11 AM3/7/15
to phon...@googlegroups.com
Kerri,

Thanks. Have submitted a bug report to the plugins team. Be interested to see how it turns out. Still worried its my code though :)

Also have built and tested the same code for watchPosition and can see that doesn't have the same memory issues, So I do have a way forward, though I have to change the architecture. Its only a few hours work though I'll wait to see what comes back from the plugins team. 

Thanks for the help, its been a pleasure. let me know if you ever hit London.

Rob.

Greg Allensworth

unread,
Mar 9, 2015, 12:05:50 PM3/9/15
to phon...@googlegroups.com
Hey, Rob. It's a day late, but at least I can confirm that you're right.

An app which has already initialized, and is now sitting quietly on
another table, pinging for location every 3 seconds... is showing an
incremental increase in memory usage. And when I cancelInterval() this
ceases. And that's just getting location with "function(){}" as a
success handler. Reinstate the interval and memory creeps upward.

Switching to watchPosition() does alleviate this and keep a flat memory
usage. The responsiveness isn't as nice, but given the choice of the
application being terminated in an hour I think it will do.

So, thank you for pointing this out. It did lead me to double-check my
own application and head off a potential issue down the road.

-g
> --
> -- You received this message because you are subscribed to the Google
> Groups "phonegap" group.
> To post to this group, send email to phon...@googlegroups.com
> <mailto:phon...@googlegroups.com>
> To unsubscribe from this group, send email to
> phonegap+u...@googlegroups.com
> <mailto:phonegap%2Bunsu...@googlegroups.com>
> For more options, visit this group at
> http://groups.google.com/group/phonegap?hl=en?hl=en
>
> For more info on PhoneGap or to download the code go to
> www.phonegap.com <http://www.phonegap.com>
> ---
> You received this message because you are subscribed to the Google
> Groups "phonegap" group.
> To unsubscribe from this group and stop receiving emails from it,
> send an email to phonegap+u...@googlegroups.com
> <mailto:phonegap+u...@googlegroups.com>.
> For more options, visit https://groups.google.com/d/optout.
>
>
> --
> -- You received this message because you are subscribed to the Google
> Groups "phonegap" group.
> To post to this group, send email to phon...@googlegroups.com
> To unsubscribe from this group, send email to
> phonegap+u...@googlegroups.com
> For more options, visit this group at
> http://groups.google.com/group/phonegap?hl=en?hl=en
>
> For more info on PhoneGap or to download the code go to www.phonegap.com
> ---
> You received this message because you are subscribed to the Google
> Groups "phonegap" group.
> To unsubscribe from this group and stop receiving emails from it, send
> an email to phonegap+u...@googlegroups.com
> <mailto:phonegap+u...@googlegroups.com>.
> For more options, visit https://groups.google.com/d/optout.


--
Greg Allensworth, Senior Web GIS Developer
BS A+ Network+ Security+ Linux+ Server+

GreenInfo Network - Information and Mapping in the Public Interest
564 Market Street, Suite 510 San Francisco CA 94104
PH: 541-223-7636 email: gre...@greeninfo.org
Web: www.GreenInfo.org www.MapsPortal.org

Subscribe to MapLines, our e-newsletter, at www.GreenInfo.org

Rob Willett

unread,
Mar 9, 2015, 1:00:16 PM3/9/15
to phon...@googlegroups.com
Greg,

I had the same memory issues with basically a blank function. Its quite a large memory leak as well. I wrote a small dummy app and have posted the issue on the Apache Cordova plugin issues site. So far nothing back.

I’ve switched to watchPosition. Had to change quite a lot of code as I no longer have a GPS position coming in every second which was an assumption I had made (yeah, yeah, I know about assumptions biting you in the bum).

It may be that watchPosition is actually nicer for some uses.I'm still getting my head around how to use it.

Rob


    To unsubscribe from this group, send email to
    <mailto:phonegap%2Bunsu...@googlegroups.com>
    For more options, visit this group at
    http://groups.google.com/group/phonegap?hl=en?hl=en

    For more info on PhoneGap or to download the code go to
    www.phonegap.com <http://www.phonegap.com>

    ---
    You received this message because you are subscribed to the Google
    Groups "phonegap" group.
    To unsubscribe from this group and stop receiving emails from it,

    For more options, visit https://groups.google.com/d/optout.


--
-- You received this message because you are subscribed to the Google
Groups "phonegap" group.
To post to this group, send email to phon...@googlegroups.com
To unsubscribe from this group, send email to

For more options, visit this group at
http://groups.google.com/group/phonegap?hl=en?hl=en

For more info on PhoneGap or to download the code go to www.phonegap.com
---
You received this message because you are subscribed to the Google
Groups "phonegap" group.
To unsubscribe from this group and stop receiving emails from it, send

For more options, visit https://groups.google.com/d/optout.


--
Greg Allensworth, Senior Web GIS Developer
BS  A+  Network+  Security+  Linux+  Server+

GreenInfo Network - Information and Mapping in the Public Interest
564 Market Street, Suite 510  San Francisco CA 94104
PH: 541-223-7636    email: gre...@greeninfo.org
Web: www.GreenInfo.org     www.MapsPortal.org

Subscribe to MapLines, our e-newsletter, at www.GreenInfo.org
--
-- You received this message because you are subscribed to the Google
Groups "phonegap" group.
To post to this group, send email to phon...@googlegroups.com
To unsubscribe from this group, send email to

For more options, visit this group at
http://groups.google.com/group/phonegap?hl=en?hl=en

For more info on PhoneGap or to download the code go to www.phonegap.com
--- You received this message because you are subscribed to the Google Groups "phonegap" group.
To unsubscribe from this group and stop receiving emails from it, send an email to phonegap+unsubscribe@googlegroups.com.

Greg Allensworth

unread,
Mar 9, 2015, 1:13:57 PM3/9/15
to phon...@googlegroups.com
I too had written originally in watchPosition() but was not satisfied
with location updates being as infrequent as they were, since this
application is pretty responsive and proactive: pinging for nearby
features, updating a listing with distance/direction readouts, as well
as toggling auto-centering of a map off and on (see below)...

Switching over to getCurrentPosition() solved all of these: every 3
seconds I know for a fact there will be a location update, and if they
had turned auto-centering on 2.9 seconds ago then we're still good, right?

Switching over to watchPosition() does mean reinstating some of those
earlier considerations. Example: if they turn on auto-centering of the
map, they probably want it centered right now. If you're using
watchPosition() and they turn on auto-centering ... then there is no
position update, and the map won't auto-center until they wave their
arms around and walk in a circle. Workaround: upon turning on
auto-center, you'd explicitly do a getCurrentPosition() and hand off to
presumably that selfsame on-location-event handler you're already using.

If you're already using setInterval() over getCurrentPosition() then
your starting point is to change literally two lines of code. But it's
small considerations like that auto-centering expectation, which the
changeover "more interesting".

-g
> <mailto:kerri...@gmail.com <mailto:kerri...@gmail.com>>__>
> wrote:
>
> The place to submit issues would be here:
> https://issues.apache.org/__jira/browse/CB
> navigator.geolocation.__watchPosition(onSuccess,
> onFailure,
> options);
> }
> document.addEventListener("__deviceready", start,
> phon...@googlegroups.com <mailto:phon...@googlegroups.com>
> <mailto:phonegap@googlegroups.__com
> <mailto:phon...@googlegroups.com>>
> To unsubscribe from this group, send email to
> phonegap+unsubscribe@__googlegroups.com
> <mailto:phonegap%2Bunsu...@googlegroups.com>
> <mailto:phonegap%__2Buns...@googlegroups.com
> <mailto:phonegap%252Buns...@googlegroups.com>__>
> For more options, visit this group at
> http://groups.google.com/__group/phonegap?hl=en?hl=en
> <http://groups.google.com/group/phonegap?hl=en?hl=en>
>
> For more info on PhoneGap or to download the code go to
> www.phonegap.com <http://www.phonegap.com> <http://www.phonegap.com>
> ---
> You received this message because you are subscribed to the
> Google
> Groups "phonegap" group.
> To unsubscribe from this group and stop receiving emails
> from it,
> send an email to phonegap+unsubscribe@__googlegroups.com
> <mailto:phonegap%2Bunsu...@googlegroups.com>
> <mailto:phonegap+unsubscribe@__googlegroups.com
> <mailto:phonegap%2Bunsu...@googlegroups.com>>.
> For more options, visit
> https://groups.google.com/d/__optout
> <https://groups.google.com/d/optout>.
>
>
> --
> -- You received this message because you are subscribed to the
> Google
> Groups "phonegap" group.
> To post to this group, send email to phon...@googlegroups.com
> <mailto:phon...@googlegroups.com>
> To unsubscribe from this group, send email to
> phonegap+unsubscribe@__googlegroups.com
> <mailto:phonegap%2Bunsu...@googlegroups.com>
> For more options, visit this group at
> http://groups.google.com/__group/phonegap?hl=en?hl=en
> <http://groups.google.com/group/phonegap?hl=en?hl=en>
>
> For more info on PhoneGap or to download the code go to
> www.phonegap.com <http://www.phonegap.com>
> ---
> You received this message because you are subscribed to the Google
> Groups "phonegap" group.
> To unsubscribe from this group and stop receiving emails from
> it, send
> an email to phonegap+unsubscribe@__googlegroups.com
> <mailto:phonegap%2Bunsu...@googlegroups.com>
> <mailto:phonegap+unsubscribe@__googlegroups.com
> <mailto:phonegap%2Bunsu...@googlegroups.com>>.
> For more options, visit https://groups.google.com/d/__optout
> <https://groups.google.com/d/optout>.
>
>
>
> --
> Greg Allensworth, Senior Web GIS Developer
> BS A+ Network+ Security+ Linux+ Server+
>
> GreenInfo Network - Information and Mapping in the Public Interest
> 564 Market Street, Suite 510 San Francisco CA 94104
> PH: 541-223-7636 <tel:541-223-7636> email: gre...@greeninfo.org
> <mailto:gre...@greeninfo.org>
> Web: www.GreenInfo.org <http://www.GreenInfo.org> www.MapsPortal.org
> <http://www.MapsPortal.org>
>
> Subscribe to MapLines, our e-newsletter, at www.GreenInfo.org
> <http://www.GreenInfo.org>
>
>
> --
> -- You received this message because you are subscribed to the Google
> Groups "phonegap" group.
> To post to this group, send email to phon...@googlegroups.com
> <mailto:phon...@googlegroups.com>
> To unsubscribe from this group, send email to
> phonegap+unsubscribe@__googlegroups.com
> <mailto:phonegap%2Bunsu...@googlegroups.com>
> For more options, visit this group at
> http://groups.google.com/__group/phonegap?hl=en?hl=en
> <http://groups.google.com/group/phonegap?hl=en?hl=en>
>
> For more info on PhoneGap or to download the code go to
> www.phonegap.com <http://www.phonegap.com>
> --- You received this message because you are subscribed to the
> Google Groups "phonegap" group.
> To unsubscribe from this group and stop receiving emails from it,
> send an email to phonegap+unsubscribe@__googlegroups.com
> <mailto:phonegap%2Bunsu...@googlegroups.com>.
> For more options, visit https://groups.google.com/d/__optout
> <https://groups.google.com/d/optout>.
>
>
> --
> -- You received this message because you are subscribed to the Google
> Groups "phonegap" group.
> To post to this group, send email to phon...@googlegroups.com
> To unsubscribe from this group, send email to
> phonegap+u...@googlegroups.com
> For more options, visit this group at
> http://groups.google.com/group/phonegap?hl=en?hl=en
>
> For more info on PhoneGap or to download the code go to www.phonegap.com
> ---
> You received this message because you are subscribed to the Google
> Groups "phonegap" group.
> To unsubscribe from this group and stop receiving emails from it, send
> an email to phonegap+u...@googlegroups.com
> <mailto:phonegap+u...@googlegroups.com>.

Rob Willett

unread,
Mar 9, 2015, 1:36:25 PM3/9/15
to phon...@googlegroups.com
Greg,

My testing has just been with the simulator as I still think about how to handle things. 

My app has a master scheduler which handles all the complex scheduling, e.g. go and get my GPS position, go and get some data from a server, upload some data. The actions the scheduler must perform are all defined in a framework so plugging in extra actions isn't a problem. The scheduler knows nothing of GPS, just the fact it needs to execute something at some time. Its very UNIX-like, simple stuff doing simple things. Put the complexity elsewhere.

The fact that watchPosition is on a separate timer is a slight hassle as we have to collect the output from that timer when something happens and plug it back into the master scheduler. Its a small semaphore problem and just needs some careful thinking to avoid boundary conditions. If nothing comes back from the watchPosition (assuming no error), thats fine as the master scheduler will still execute every second and use the currentGPS as we know nothing has moved. The key for us is to separate out the various timers and make sure the comms into the master scheduler are nice, simple and clean. 

As we still have a GPS position, the auto-entering is not a problem for us as we have an event (note I haven't said its a new GPS event) coming at one second intervals from the master scheduler. The master scheduler is the drumbeat that everything works to. If nothing has changed we still have the right GPS position. If the GPS position has changed from the last time, the master scheduler action picks it up and sends it on. The major change for us is passing the right information from watchPosition into the master scheduler correctly. 

The other advantage is that it *may* use less battery power. Need to check that somehow, no idea at the moment.

 Now if we get an error that's something we haven't worked through yet.

We may well stay with watchPosition as there are advantages, by tomorrow we will be able to use either :)

Rob

Kerri Shotts

unread,
Mar 9, 2015, 3:48:46 PM3/9/15
to phon...@googlegroups.com
Some of my thoughts in no particular order:

1. Depending on the device and the implementation, watchPosition can allow for improved battery life, since one isn't continuously polling for changes. The device can, instead, notify the app when the location changes by some threshold. If the user isn't moving, there's no reason to keep sending updates. If the user is moving, the device might actually send updates more frequently than a polling threshold. 

I'm not going to speculate as to which platforms do and do not do this. But for those that do (even if only in the future), I'd highly suggest watchPosition vs polling.

2. The issue of centering your map can be solved in one of two ways:
    a. request getCurrentPosition explicitly. Because the geolocation object is the same for either event, your handler should be able to accept events from watchPosition and getCurrentPosition.
    b. cache the previously known position and center there. If the user is not moving, it will be sufficiently close to their position. If the user /is/ moving, it should also be sufficiently close, and if not, the next notification from watchPosition will update your view.

3. There's no guarantee that getCurrentPosition/watchPosition will return results in a timely manner. In this case, there's no sense sending multiple requests if they are all going to time out. Or, if they all take more than your polling interval (for whatever reason), then you're also polling more than necessary. If you must poll, you could schedule the next check only when you receive a good response from the last request using setTimeout. (Of course, right now you have the same memory leak.)

Not that this means that the leak shouldn't be fixed: it should. That said, I'm having difficulty imagining a scenario where polling getCurrentPosition would be better than using watchPosition. My advice would always be use watchPosition when you need to track the user's location, and use getCurrentPosition when you need a one-off. Cache the last known position liberally, as well.
Reply all
Reply to author
Forward
0 new messages