-
Notifications
You must be signed in to change notification settings - Fork 94
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Nativescript Mapbox on iOS retain memory after navigation away #67
Comments
Created a sample project with this problem. |
Thanks for the sample! When attaching a profiler and going back and forth between those 2 pages I can see that memory builds up. Looks like JS is keeping a reference (possibly Angular even). Can you try changing import { Component } from "@angular/core";
import {RouterExtensions} from "nativescript-angular/router";;
import * as utils from "utils/utils";
@Component({
selector: 'tap',
templateUrl: "tap.component.html",
})
export class TapComponent {
public counter: number = 16;
constructor(
private _routerExtensions: RouterExtensions
) { }
public get message(): string {
if (this.counter > 0) {
return this.counter + " taps left";
} else {
return "Hoorraaay! \nYou are ready to start building!";
}
}
public onTap() {
this.counter--;
console.log("--- doing GC");
utils.GC();
}
public onMapTap() {
this._routerExtensions.navigate(["/map"]);
// <any> { clearHistory: true });
}
} And tap the 'tap' button after each visit to the map? Curious to learn if that fixes your crash as |
@ahalls do you have the same problem if you define maps in code instead of XML ? I have 2 projects running mapbox plugin in classic JS and Typescript. The one with map defined in XML is eating a lot of memory and gets killed. The other project has map defined in code and is running fine. (eating memory but at much lower pace). I have not checked this further since maps defined in code is working for me at the moment. |
@Stavanger75 I have not tried creating the map from code. I need to place the map in the context of other components. I didn't see a way to find a container and place the map in the container from code. Is there a way? |
@EddyVerbruggen directly calling a GC() a little bit after the navigating from the Map page with the significantly reduces the growth of the memory footprint of the app. There is still leaked memory ~20MB instead of ~300 MB as I had before. It was even worse until I started using |
Thanks for confirming that. I think for now you'll need this silly workaround since getting to the rootcause will be very hard. The leak may be caused by many things and thus will take quite some time to figure out. |
@ahalls I have not used Angular 2 i am afraid only 1.x so i can unfortunately not help you with creating angular component. I use classic JS with Typescript only. Good calling GC() helped on some of the memory leak. Hope you get it sorted out. |
I've found a similar issue with Android as well. |
This issue solved? Or does anyone know of another plugin without the memory leak? My entire app is the map so it's critical :( |
@EddyVerbruggen client put the project on hold :/ Been watching this thread though to see any updates, I love Mapbox and use it heavily on the web |
@EddyVerbruggen Still having problems with this issue. Calling GC() all over the place. |
@EddyVerbruggen I'm going to try to call
the destroy() call return undefined method on object |
@ahalls Can you please try that again with 2.6.1? |
With the above referenced test app. I do a GC on ngInit ... It is probably good enough for our application. But not for a full scale (web scale) production app. I don't think you should close this issue. |
hey @ahalls, did you find any solutions or workaround? I trying different things to solve this memory issue. The problem in our app is that it is in a RadSideDrawer, so the map could be called several times and so memory increase continuosly; the gc command is helping but not a lot. any ideas? thanks in advance |
Why do you have multiple instances of the sidedrawer? |
hi @EddyVerbruggen and thanks for the quick reply. But the problem is not the multiple instance of the map, in another app there is just the map page in the menù and others pages. Still entering in the map page and in another and then back in the map page the memory increases, so there I'm using the utils.gc() and I'm destroying the map. I was thinking on creating the map by code in the app.component and showing and hiding when I need it and not calling every time in a different html file. |
I'm not sure what exactly causes the map to be retained. I mean, when the page goes off the stack and is destroyed and gc'd, the map should be removed from memory as well. If that's not the case then I'm not sure why exactly. |
@EddyVerbruggen I've created a repository here to test what I wrote above. https://github.com/simonettoa/my-drawer-ng In the readMe file there are the instructions and also some tests data I've made. Now I will try a different approach to figured it out this memory retain issue. If you have any suggestions it will be very appreciated UPDATE: I've updated the solution posted above and calling the map box through a modal page is the best solution to clear the memory(it's still increasing but not as before) ; at least in ios; didn't try in android but I assume it is the correct way to proceed! if anybody has a better solution post it, thanks |
I've tested the android part and is not working, the map doesn't appear in the modal page, it appears in the browse page (iOS works), any clue why? |
@simonettoa Did you update the demo to run in a modal? Looks like the current version on Github sits inside a sidedrawer. |
@EddyVerbruggen I've just updated the project. the modal page solution doesn't work in android. Tested to add the map programatically and use the hide and unhide property. It works good in ios, it doesn't add any memory because the map is created once. In android it does not work when you change the page. To test it go from the home page to search page, click on the actionBar map's icon, first time you'll see the map, click on the menu on the top left the hide property is called, go to settings page and back to search, click again you'll see the map (in this page is just using hide and unhide). In android the same behaviour is not replied, you'll see the first time the map and the click on the map's icon is playing with hide/unhide (of the local page mapbox) - click on the menu will set the unhide to the app.component map and the current one; the click again will fires the unhide on the app.component map but it won't appear. In featured page it works little different, when you click on the menu icon the destroy fuction is called; it will work logically but the every time the map is called the show function is also and the memory will increase as usual. Still looking to a good solution... |
Looking inside the library I can see that in ios the functions hide/unhide call removeFromSuperview/addSubview. In android it uses to change the setVisibility of the view (INVISIBLE/VISIBLE). Probably nativescript is putting the current page on top. I'm trying to see if I can do a similar thing adding and removing the map in android as it's done in ios . Strange behaviour that I've noticed and maybe could help to find out a solution; now the demo I've done uses to hide and unhide the map through the current page component based on the shared map's app.component. If I try to use directly the hide function on the 'shared' map object it won't re-appear. |
SOLUTION FOUND!!! Basically to make it work also in android the solution was to change in app.component.html from page-outer-outlet to outer-outlet. Connected with this change is also necessary to fix some stuff in order to have the graphic to appear properly. Right now from the home page and going to browse or search page you'll see a map icon on right-top, clicking on it and the map will appear with two markers. Going to the another page will hide the map and going to the search page and clicking on the map's icon the map will appear and different markers. The project shared in older post is updated. |
Thanks for sharing, @simonettoa! I'm about to release plugin version 4.0.0 which includes Mapbox iOS SDK version 4.0.0 which (as far as I can see from their changelog) contains a bunch of memory leaks. Perhaps that will help as well. Closing for now. |
Hey, Have you released the plugin? |
I'm using Angular 2, with router-outlet navigation. My app is killed by the OS for using too much memory after I navigate away from the page with the MapBox map and return. It's clear that the memory associated with the Mapbox instance is not being released.
I put a log statement in ngOnDestroy() and it is being called when I expect it to be. Is there anything I can do to force the SDK to release memory?
I'm instantiating the map via XML
This component is instantiated in the page via Angular2 router-outlet navigation.
How can I further debug this issue?
The text was updated successfully, but these errors were encountered: