{"action":"created","issue":{"url":"https://api.github.com/repos/telerik/nativescript-ui-feedback/issues/825","repository_url":"https://api.github.com/repos/telerik/nativescript-ui-feedback","labels_url":"https://api.github.com/repos/telerik/nativescript-ui-feedback/issues/825/labels{/name}","comments_url":"https://api.github.com/repos/telerik/nativescript-ui-feedback/issues/825/comments","events_url":"https://api.github.com/repos/telerik/nativescript-ui-feedback/issues/825/events","html_url":"https://github.com/telerik/nativescript-ui-feedback/issues/825","id":357064856,"node_id":"MDU6SXNzdWUzNTcwNjQ4NTY=","number":825,"title":"RLV Memory leak in Angular application","user":{"login":"NathanaelA","id":850871,"node_id":"MDQ6VXNlcjg1MDg3MQ==","avatar_url":"https://avatars3.githubusercontent.com/u/850871?v=4","gravatar_id":"","url":"https://api.github.com/users/NathanaelA","html_url":"https://github.com/NathanaelA","followers_url":"https://api.github.com/users/NathanaelA/followers","following_url":"https://api.github.com/users/NathanaelA/following{/other_user}","gists_url":"https://api.github.com/users/NathanaelA/gists{/gist_id}","starred_url":"https://api.github.com/users/NathanaelA/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/NathanaelA/subscriptions","organizations_url":"https://api.github.com/users/NathanaelA/orgs","repos_url":"https://api.github.com/users/NathanaelA/repos","events_url":"https://api.github.com/users/NathanaelA/events{/privacy}","received_events_url":"https://api.github.com/users/NathanaelA/received_events","type":"User","site_admin":false},"labels":[{"id":485849358,"node_id":"MDU6TGFiZWw0ODU4NDkzNTg=","url":"https://api.github.com/repos/telerik/nativescript-ui-feedback/labels/listview","name":"listview","color":"eb6420","default":false},{"id":848709283,"node_id":"MDU6TGFiZWw4NDg3MDkyODM=","url":"https://api.github.com/repos/telerik/nativescript-ui-feedback/labels/new%20PR","name":"new PR","color":"ededed","default":false},{"id":730325698,"node_id":"MDU6TGFiZWw3MzAzMjU2OTg=","url":"https://api.github.com/repos/telerik/nativescript-ui-feedback/labels/severity:%20critical","name":"severity: critical","color":"b60205","default":false}],"state":"open","locked":false,"assignee":{"login":"VladimirAmiorkov","id":4989411,"node_id":"MDQ6VXNlcjQ5ODk0MTE=","avatar_url":"https://avatars2.githubusercontent.com/u/4989411?v=4","gravatar_id":"","url":"https://api.github.com/users/VladimirAmiorkov","html_url":"https://github.com/VladimirAmiorkov","followers_url":"https://api.github.com/users/VladimirAmiorkov/followers","following_url":"https://api.github.com/users/VladimirAmiorkov/following{/other_user}","gists_url":"https://api.github.com/users/VladimirAmiorkov/gists{/gist_id}","starred_url":"https://api.github.com/users/VladimirAmiorkov/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/VladimirAmiorkov/subscriptions","organizations_url":"https://api.github.com/users/VladimirAmiorkov/orgs","repos_url":"https://api.github.com/users/VladimirAmiorkov/repos","events_url":"https://api.github.com/users/VladimirAmiorkov/events{/privacy}","received_events_url":"https://api.github.com/users/VladimirAmiorkov/received_events","type":"User","site_admin":false},"assignees":[{"login":"VladimirAmiorkov","id":4989411,"node_id":"MDQ6VXNlcjQ5ODk0MTE=","avatar_url":"https://avatars2.githubusercontent.com/u/4989411?v=4","gravatar_id":"","url":"https://api.github.com/users/VladimirAmiorkov","html_url":"https://github.com/VladimirAmiorkov","followers_url":"https://api.github.com/users/VladimirAmiorkov/followers","following_url":"https://api.github.com/users/VladimirAmiorkov/following{/other_user}","gists_url":"https://api.github.com/users/VladimirAmiorkov/gists{/gist_id}","starred_url":"https://api.github.com/users/VladimirAmiorkov/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/VladimirAmiorkov/subscriptions","organizations_url":"https://api.github.com/users/VladimirAmiorkov/orgs","repos_url":"https://api.github.com/users/VladimirAmiorkov/repos","events_url":"https://api.github.com/users/VladimirAmiorkov/events{/privacy}","received_events_url":"https://api.github.com/users/VladimirAmiorkov/received_events","type":"User","site_admin":false}],"milestone":null,"comments":12,"created_at":"2018-09-05T04:50:03Z","updated_at":"2018-10-11T07:48:30Z","closed_at":null,"author_association":"NONE","body":"## Please, provide the details below:\r\n\r\n### Did you verify this is a real problem by searching the [NativeScript Forum]\r\nYes, this is related to #822; My clients app is actually a Angular app; and apparent this issue is only visible in an Angular app, not in the original PAN app I provided.   I thought they were the same issue as the result looked the same between my test PAN app and my clients NAN app.   Since I was trying to give you the reduced test case, I proceeded with that report.  However #822 ends up just being a GC timing issue in the Pan app that mimics this issue; until a native GC actually fires.\r\n\r\nThis version of the bug report has a reduced test case in a NAN app which can show off the issue properly that we are seeing.\r\n\r\n### Tell us about the problem\r\nBasically the issue is that memory is leaked on each refresh of the listview in an Angular app.    Whatever elements were in the template are are basically leaked.  \r\n\r\n### Which platform(s) does your issue occur on?\r\nAndroid\r\n\r\n### Please provide the following version numbers that your issue occurs with:\r\n- **Progress ListView UI version:** 3.6.1 (Latest)\r\n- **CLI:** 4.2\r\n- **Cross-platform modules:** 4.2\r\n- **Cross-platform Widgets**: 4.3-@NEXT\r\n- **Runtime(s):** 4.2\r\n\r\n### Please tell us how to recreate the issue in as much detail as possible.\r\n1. Start the application `tns debug android`\r\n2. Take a Chrome Heap SnapShot\r\n3. Pull to Refresh, Pull to Refresh, Pull to Refresh\r\n4. Take a Chrome Heap SnapShot\r\nYou can repeat steps 3 & 4 over and over and you will see that the memory is not returned.\r\n\r\nThe refresh code causes both a Java and V8 GC (attempts to trigger one).  So this should eventually after one of the pull to refreshes cause all the prior garbage to be collected.  So after 6 refreshes, GC should have ran at least once because we triggered both 6 times.    I have continued this refresh over and over and eventually I had over 300 Labels in memory.   Since it starts with only 17, you can see GC should have at least ran in one of the 20 odd times I refreshed...    In addition if you switch pages and then back; the labels from the ListView are still retained in memory, and new labels are created. \r\n\r\nStep 2 (First Snapshot):\r\n![image](https://user-images.githubusercontent.com/850871/45070078-3d4ef300-b095-11e8-8e4c-947aed0414c8.png)\r\nStep 4 (Second Snapshot, 3 refreshes):\r\n![image](https://user-images.githubusercontent.com/850871/45070098-4cce3c00-b095-11e8-9656-7188c87bb580.png)\r\nStep 6 (Third Snapshot: 3 more refreshes)\r\n![image](https://user-images.githubusercontent.com/850871/45070115-5eafdf00-b095-11e8-83d1-d613ff3c2972.png)\r\n\r\n\r\n### Is there code involved? \r\nI used the Kinsey Master/Detail Angular template; and added a couple minor changes to it (updated the packages.json to use the latest widgets and RLV).   Added the GC code; move the init into a refresh function and finally enabled pull to refresh.\r\n\r\nAttached is the modified project.\r\n[testlistng.zip](https://github.com/telerik/nativescript-ui-feedback/files/2351257/testlistng.zip)\r\n\r\n---\r\n**Notes**:\r\n\r\nIn addition based on looking into this issue the leak appears to be related to the angular code that deals with debug tracking.  This structure maintains a \"DebugElement\" to every created element.\r\n\r\n![image](https://user-images.githubusercontent.com/850871/45070421-ce729980-b096-11e8-991c-bcfa37783225.png)\r\n\r\nIf you modify the code in `node_modules/@angular/core/bundles/core.umd.js` and replace the _nativeNodeToDebugNodeDebug code at line 5448 with this:\r\n```\r\n   // Need to keep the nodes in a global Map so that multiple angular apps are supported.\r\n    var _nativeNodeToDebugNode = new Map();\r\n    /**\r\n     * @experimental\r\n     */\r\n    function getDebugNode(nativeNode) {\r\n        return _nativeNodeToDebugNode.get(nativeNode) || null;\r\n    }\r\n    var labelCounter=0;\r\n    function indexDebugNode(node) {\r\n        if (node && node.nativeNode && node.nativeNode.nodeName === \"Label\") {\r\n            labelCounter++;\r\n            console.log(\"indexDebugNode, Add Label, Count: \", labelCounter);\r\n        }\r\n        _nativeNodeToDebugNode.set(node.nativeNode, node);\r\n    }\r\n    function removeDebugNodeFromIndex(node) {\r\n        if (node && node.nativeNode && node.nativeNode.nodeName === \"Label\") {\r\n            labelCounter--;\r\n            console.log(\"removeDebugNodeFromIndex, delete Label, Count: \", labelCounter);\r\n        }\r\n        _nativeNodeToDebugNode.delete(node.nativeNode);\r\n    }\r\n```\r\nYou will see that `indexDebugNode` is triggered and `removeDebugNodeFromIndex` is not triggered during a pull to refresh.    Whatever steps is supposed to trigger the `removeDebugNodeFromIndex` is not happening; and so the Label (and everything related to it) is retained forever by the `_nativeNodeToDebugNode` map.   In addition, I needed to use the if statement to limit it to just the \"Labels\", because in all reality pretty much every created element is put into this structure (starts with 86 items on first run).  And this tracking map had over 1000 items retained by the time I was done running my last test.  So I wanted to just show the memory used with just `Labels`\r\n\r\n![image](https://user-images.githubusercontent.com/850871/45070584-886a0580-b097-11e8-887d-e206b03f0c83.png)\r\n\r\n**Additional Notes:**\r\nIf you do navigate to the detail page and then back; you will see that 14 indexDebugNode are called and then when you leave you will see 14 RemoveDebugNodeFromIndex are called on those created Labels.   So apparently the Debug tracking code isn't totally broken, as it does clean up after itself in that case correctly."},"comment":{"url":"https://api.github.com/repos/telerik/nativescript-ui-feedback/issues/comments/428855698","html_url":"https://github.com/telerik/nativescript-ui-feedback/issues/825#issuecomment-428855698","issue_url":"https://api.github.com/repos/telerik/nativescript-ui-feedback/issues/825","id":428855698,"node_id":"MDEyOklzc3VlQ29tbWVudDQyODg1NTY5OA==","user":{"login":"NathanaelA","id":850871,"node_id":"MDQ6VXNlcjg1MDg3MQ==","avatar_url":"https://avatars3.githubusercontent.com/u/850871?v=4","gravatar_id":"","url":"https://api.github.com/users/NathanaelA","html_url":"https://github.com/NathanaelA","followers_url":"https://api.github.com/users/NathanaelA/followers","following_url":"https://api.github.com/users/NathanaelA/following{/other_user}","gists_url":"https://api.github.com/users/NathanaelA/gists{/gist_id}","starred_url":"https://api.github.com/users/NathanaelA/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/NathanaelA/subscriptions","organizations_url":"https://api.github.com/users/NathanaelA/orgs","repos_url":"https://api.github.com/users/NathanaelA/repos","events_url":"https://api.github.com/users/NathanaelA/events{/privacy}","received_events_url":"https://api.github.com/users/NathanaelA/received_events","type":"User","site_admin":false},"created_at":"2018-10-11T07:48:30Z","updated_at":"2018-10-11T07:48:30Z","author_association":"NONE","body":"Hi @VladimirAmiorkov,\r\n\r\nThanks for the feedback; I realize their are two other PR's that need to be released for the fix to take full effect.    So just to confirm, because I'm confused by your wording.    The current version of RLV now contains the needed fixes that it needed.   So if I manually add the other two PR's to my app; I should see this issue fixed, correct?"}}
{"actor":{"display_login":"NathanaelA"}}