Page 1 of 3 123 LastLast
Results 1 to 10 of 23

Thread: [iOS 3.0.3] While navigating, memory keeps growing until iOS kills my app.

  1. #1
    Erfahrener skobbler
    Join Date
    11.02.2015
    Posts
    123

    [iOS 3.0.3] While navigating, memory keeps growing until iOS kills my app.

    Since I implemented SKMaps 3 in my app, users have been complaining about crashes while navigating / free driving. After analyses turns out my app is being killed by iOS due to excessive memory usage. (In case it matters: while on 2.5.1 I was using light maps, which are no longer available in 3.) Before you ask... I am quite positive my own code does not contain any memory leaks. This has been thoroughly analysed and fixed in earlier stages of development and also I didn't really change anything else when updating to 3 and there were no complaints when my app was still using 2.5.1 with light maps.

    While navigating, memory keeps on growing until a low memory warning is received. After analyses with Xcode's Instruments I see that memory is being freed when this warning is received, however apparently not always enough. I'm not sure, but it looks to me that some abandoned or leaked memory stays behind. Mostly in the form of non-object. I've been able to reproduce this in the (Swift) Demo App.

    Steps to reproduce in the demo app on simulator:
    1. In NavigationUIViewController
    - Comment out lines 31, 32, 33, 68, 69
    - between lines 69 and 70 add new lines:
    
mapView.settings.followUserPosition = true

    mapView.settings.displayMode = .mode3D

    mapView.settings.headingMode = .route

    mapView.animate(toZoomLevel: 8)
    - change line 43
    
from: navigationManager.startNavigation(with: configuration)

    to: navigationManager.startFreeDrive(with: configuration)

    2. Run the project in the iOS simulator (I used iPhone5SE)
    3. In the simulator 'Debug' menu select -> Location -> Apple
    4. Stop running the app
    5. Open Instruments
    6. Select the Allocations Tool
    7. Run the demo project from there (again on the iPhoneSE simulator for me)
    8. In the app select the Navigation UI (free drive will start)
    9. In the instruments tool do "Mark Generation' (I'm seeing an an initial growth of about 200MB) (on an actual device, iPhone6, this is only 95MB for the demo app and 110MB for my app)
    10. Now go to the simulator menu Debug -> Location -> Freeway drive (the map will start moving)
    11. In Instruments do a 'mark generation' every minute or so. You'll see the growth will be in the 5 MB range (sometimes more sometimes less) between the generations.
    12. After doing a 'Mark generation' for about 5 times, simulate a low memory warning (Simulator -> Hardware -> Simulate Memory Warning). 
You'll see overall memory footprint going down, but even for the earlier generations the growth remains more or less equal. This growth is mostly due to non-object

    Steps to reproduce with the demo app on a device
    1. Run the modified demo project on your device (ideally a bit older device, like iPhone 5).
    2. Open up a lot of big apps (memory hogs) like Facebook, some other navigation apps, etc.
    3. Then open the demo app, tap 'Navigation UI' and start driving.
    4. Sometimes after 5 minutes, sometimes after 3 hours, the app will crash

    Now, I'm not sure about the behaviour of the framework when a low memory warning is received, but I do know that the 'cleanup' is not always sufficient to prevent the app from crashing. As I said I am quite certain that my own code does not contain any substantial leaks because the difference in memory footprint of my app compared to the demo app always stays around the 15MB, which it initially also was, and there were no crashes when running 2.5.1 with light maps.

    I've already tried this:
    mapView?.settings.showStreetBadges = false
    mapView?.settings.showStreetNamePopUps = true
    mapView?.settings.showHouseNumbers = false
    mapView?.settings.poiDisplayingOption = SKPOIDisplayingOption(rawValue: 0)
    mapView?.settings.showOneWays = false
    But that didn't seem to effect the footprint nor cleanup.


    So, basically I'm looking for a solution to manage the frameworks memory footprint (more specifically the in memory map tiles cache) (and of course if there are leaks/abondoned memory in the framework they would ideally have to be fixed.) For example a way to set the the map tiles cache (in memory) to a maximum size, or, to have more influence on the 'clean up' method that's executed when a low memory warning is received (i.e. clean up more from the cache).

    I've asked this question already on Stack Overflow, where I was pointed to SKTilesCacheManager, but as I understand it that's only to manage the cashing of map tiles on DISK, not in memory.

    Is there a way to manage the frameworks memory footprint? If not, are there any plans to create this? Or perhaps better, to create a more dynamic and proactive way to manage to map tiles cache in memory, so that the app acts before ever receiving the low memory warning?
    And, are there any other things I could try perhaps?
    Last edited by guidove; 14.03.2017 at 00:59.

  2. #2
    Etablierter skobbler
    Join Date
    15.03.2017
    Posts
    11
    Same here.

  3. #3
    Erfahrener skobbler
    Join Date
    12.09.2016
    Posts
    112
    @guidove Could you please send us the file obtained after analysing the memory allocation and possible memory leak with Instruments tool, when the issue is being reproduced? It would help us investigate it.

  4. #4
    Erfahrener skobbler
    Join Date
    11.02.2015
    Posts
    123
    Hi Adrian,

    Sorry, I didn't see your reply sooner.
    I had to make a new trace with instruments. Here it is: https://db.tt/Lwfth1zTf2

    I followed the same procedure as above to modify the demo project and create the instruments trace.
    - Generation A is the initial growth (after going to the navigation UI)
    - After Generation A I started the location simulation ('Freeway Drive') through the simulator (not the framework's provided simulation option)
    - Generation B .. F are after 1 .. 5 minutes of location simulation respectively.
    - Between generation F and G (at around 6:30) I simulated a low memory warning and could see all generation growth go down in size, but some generations stayed in the megabytes region, some in the kb's region.
    - Generations G .. K are after 6 .. 10 minutes of location simulation respectively
    - Between K and L I simulated another low memory warning and could see the growth go down, but again some generations stayed in the megabytes region, some in the kb's region.
    - Generation L is a few seconds after the 2nd low memory warning.

    Just to be clear, this is a trace of the modified demo app, NOT my own app. I hope this helps. This should also be easily reproducible on your side by following the steps I mentioned above. Please let me know if I can help any further.

    Cheers,
    Guido

  5. #5
    Erfahrener skobbler
    Join Date
    12.09.2016
    Posts
    112
    Thanks for your effort Guido. We'll look into it asap.

  6. #6
    Erfahrener skobbler
    Join Date
    12.09.2016
    Posts
    112
    Hi Guido,
    Please let us know if you are using car or bike routing profiles, when the crashes are triggered.
    Also, do you have crashlytics integrated in your apps? If so, can you send us some of the crash logs ?
    Adrian
    Last edited by adrian.bortas; 27.03.2017 at 15:42.

  7. #7
    Erfahrener skobbler
    Join Date
    11.02.2015
    Posts
    123
    Hi Adrian,

    Sorry. Don't have crashlitics. Using car routing.
    iOS itself doesn't generate crash reports as it's not really a crash. The app just gets killed because of excessive memory usage. It does show up in the JetsamEvent reports as 'largest process'. In all cases where my app got killed it was the largest process. Did a lot of research on this. If the device memory gets low iOS first starts killing the largest background processes. And if that's not enough it kills the foreground app. This explains that my app crashes (or better, gets killed) more often when users are using it in the background. This is not uncommon for my app. A lot of users put it in their pocket while motorcycle riding and then listen to the voice guidance only.

    When users complain to me about 'chrashes' I recommend them these 3 things and I've gotten feedback that these actually help reduce and mostly prevent the crashes (or better, prevent the killing by iOS).
    1. Before you start Scenic close all other apps you don't need anymore (double tap home button and swipe up all apps)
    2. Put 'Get Map Data Online' to 'No' in Scenic settings -> Map (you would need the offline map for your area if you do that)
    3. Once every few weeks: close all apps (double tap home button and swipe up all apps) and really turn-off*your iPhone (by holding the on/off button for at least 5 seconds). Wait 10 seconds and then turn it on again.*That will basically reset the memory. Although it shouldn't happen, some apps (even Apple's own apps) leave*residual memory-allocations which then can not be allocated to apps anymore. Regardless of Scenic, this is a good practice anyway.
    By doing steps 1 and 3 you free up memory and with step 2 you reduce the memory usage of Scenic.
    Last edited by guidove; 30.03.2017 at 01:17.

  8. #8
    Erfahrener skobbler
    Join Date
    11.02.2015
    Posts
    123
    Hi Adrian,

    Although the memory growth thing needs to be investigated, I think it would already help a lot if the memory footprint of the SDK could be reduced. The problem is that the memory footprint of the SDK is just really high when navigating (so when the map is moving), which makes apps using the SDK a very likely candidate for iOS to kill first. A solution (or maybe workaround) could be to make it possible for us to set a maximum in-memory cache size. Or, if that's not possible / too much work, reduce the cache size to like 75% of what it is now, in a hotfix. Or, if it's not setup like that, clean the cache more when a low memory warning is received. What do you think?
    Last edited by guidove; 30.03.2017 at 01:23.

  9. #9
    Etablierter skobbler
    Join Date
    15.03.2017
    Posts
    11
    Adrian, we have now two reports with frequent crashes and in BOTH cases users were previously notified by their carrier that their data volume has been throttled. One of the users was (while being throttled) heading in a different direction (not the pre-cached corridor) and the app was frequently crashing – probably because new map tiles were requested on a throttled connection (internet still working, but extremely slow).

  10. #10
    Erfahrener skobbler
    Join Date
    11.02.2015
    Posts
    123
    Quote Originally Posted by cobi View Post
    Adrian, we have now two reports with frequent crashes and in BOTH cases users were previously notified by their carrier that their data volume has been throttled. One of the users was (while being throttled) heading in a different direction (not the pre-cached corridor) and the app was frequently crashing – probably because new map tiles were requested on a throttled connection (internet still working, but extremely slow).
    Hi Cobi, I'm getting similar reports. I have a setting in my app where users can choose to put the SDK connectivity mode to offline ('SKMapsService.sharedInstance().connectivityMode = SKConnectivityMode.offline'). That seems to help against the crashes, but of course will give problems if your app is only working with corridors and user goes outside the corridor.
    Are they actual crashes (do you get crash reports from them) or is it the memory issue that I'm describing above?

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •