Environment
Provide version numbers for the following components (information can be retrieved by running tns info in your project folder or by inspecting the package.json of the project):
- CLI: 5.2.0
- Cross-platform modules:
- Android Runtime: 5.2.0
- iOS Runtime:5.2.0
- Plugin(s):
- NativeScript-Angular: ~7.2.1
- Angular: ~7.2.0
Describe the bug
While working on #1728 I think I’ve found a couple of memory leaks in nativescript-angular.
ListViewComponent/TemplatedItemsComponent items.
In onItemLoading(args) https://github.com/NativeScript/nativescript-angular/blob/master/nativescript-angular/directives/templated-items-comp.ts#L141-L181
The viewRef is bound to the args.view[NG_VIEW].
This is never cleared, so when the ListViewComponent is destroyed this reference still exists.
I suggest making this a WeakRef.
The factory functions in TemplatedItemsComponent._templateMap creates a circular reference and should be cleared in ngOnDestroy()
NativeScript views lives on after the angular app have been destroyed.
The native views are destroyed as expected but according to the Chrome debugger the NativeScript views lives on.
This is caused by the AppHostView not being cleared up on exit and the firstChild, lastChild and nextSibling references are not cleaned up.
The AppHostView is reused on next launch, so it shouldn’t itself be deleted but the children should.
Sidenote: AppHostView._ngAppRoot is a reference to the last Frame even after exit, this should be solved by deleting all its children on exit.
ViewUtils.removeChild(parent, child) doesn’t remove children recursively.
ViewUtils sets up the firstChild, lastChild and nextSibling references when a view is added, but doesn’t clear them up properly when a parent view is removes.
I suggest making removeFromQueue(parent, child) and removeFromVisualTree(parent, child) recursive to clear up the references.
PageRouterOutlet doesn’t clear up it’s children.
this.activated should be destroyed in ngOnDestroy()
NSLocationStrategy don’t have an ngOnDestroy()
This leaves correntOutlet with a reference to the destroyed PageRouterOutlet.
To Reproduce
- Create a new nativescript angular app with:
tns create --ng NAME
- Launch the app on android in debug mode and start the Chrome debugger.
- Close the app by tappen the back button, reopen and close the app a few times.
- Go to the memory tab in the Chrome debugger and take a heap snapshot.
- The snapshot will have N (= number of times the app has been opened)
Frame'/ActionBar/Page/PageRouterOutlet, N*8 StackLayout` etc. The native views will have been destroyed.
- If you inspect the Views a little closer you should see they hold references to each other via
firstChild, lastChild and nextSibling
Note: It doesn't seem to matter how many times I call GC() or how long I wait.
Expected behavior
- I expect the
GC() to have collected the NativeScript Views.
Sample project
https://github.com/m-abs/tns-ng-app-lifecycle
Additional context
Environment
Provide version numbers for the following components (information can be retrieved by running
tns infoin your project folder or by inspecting thepackage.jsonof the project):Describe the bug
While working on #1728 I think I’ve found a couple of memory leaks in nativescript-angular.
ListViewComponent/TemplatedItemsComponent items.
In onItemLoading(args) https://github.com/NativeScript/nativescript-angular/blob/master/nativescript-angular/directives/templated-items-comp.ts#L141-L181
TheviewRefis bound to theargs.view[NG_VIEW].This is never cleared, so when theListViewComponentis destroyed this reference still exists.I suggest making this a
WeakRef.The factory functions in TemplatedItemsComponent._templateMap creates a circular reference and should be cleared in
ngOnDestroy()NativeScript views lives on after the angular app have been destroyed.
The native views are destroyed as expected but according to the Chrome debugger the NativeScript views lives on.
This is caused by the AppHostView not being cleared up on exit and the
firstChild,lastChildandnextSiblingreferences are not cleaned up.The AppHostView is reused on next launch, so it shouldn’t itself be deleted but the children should.
Sidenote: AppHostView._ngAppRoot is a reference to the last Frame even after exit, this should be solved by deleting all its children on exit.
ViewUtils.removeChild(parent, child) doesn’t remove children recursively.
ViewUtils sets up the
firstChild,lastChildandnextSiblingreferences when a view is added, but doesn’t clear them up properly when a parent view is removes.I suggest making removeFromQueue(parent, child) and removeFromVisualTree(parent, child) recursive to clear up the references.
PageRouterOutlet doesn’t clear up it’s children.
this.activatedshould be destroyed inngOnDestroy()NSLocationStrategy don’t have an ngOnDestroy()
This leaves
correntOutletwith a reference to the destroyedPageRouterOutlet.To Reproduce
tns create --ng NAMEFrame'/ActionBar/Page/PageRouterOutlet, N*8StackLayout` etc. The native views will have been destroyed.firstChild,lastChildandnextSiblingNote: It doesn't seem to matter how many times I call
GC()or how long I wait.Expected behavior
GC()to have collected the NativeScript Views.Sample project
https://github.com/m-abs/tns-ng-app-lifecycle
Additional context