{ "id": "145551", "key": "TIMOB-19261", "fields": { "issuetype": { "id": "1", "description": "A problem which impairs or prevents the functions of the product.", "name": "Bug", "subtask": false }, "project": { "id": "10153", "key": "TIMOB", "name": "Titanium SDK/CLI", "projectCategory": { "id": "10100", "description": "Titanium and related SDKs used in application development", "name": "Client" } }, "fixVersions": [], "resolution": null, "resolutiondate": null, "created": "2015-03-09T08:46:21.000+0000", "priority": { "name": "High", "id": "2" }, "labels": [ "android", "httpclient", "leak", "memory" ], "versions": [], "issuelinks": [], "assignee": { "name": "gmathews", "key": "gmathews", "displayName": "Gary Mathews", "active": true, "timeZone": "America/Los_Angeles" }, "updated": "2018-11-14T19:34:14.000+0000", "status": { "description": "The issue is open and ready for the assignee to start work on it.", "name": "Open", "id": "1", "statusCategory": { "id": 2, "key": "new", "colorName": "blue-gray", "name": "To Do" } }, "components": [ { "id": "10202", "name": "Android", "description": "Android Platform" } ], "description": "Using the testcase below objects keeps building up (thus increasing heap size) and never gets released.\r\n\r\nTo test open a new alloy project in titanium and edit tiapp.xml so it's debuggable and can be analyzed in Android Monitor. \r\n\r\n{code:title=index.xml|borderStyle=solid}\r\n\r\n\t\r\n\t\t\r\n\t\r\n\r\n{code}\r\n\r\n{code:title=index.js|borderStyle=solid}\r\nfunction doClick(e)\r\n{\r\n Alloy.createController('testHTTP').getView().open();\r\n}\r\n$.index.open();\r\n{code}\r\n\r\n{code:title= testHTTP.xml|borderStyle=solid}\r\n\r\n\t\r\n\t\t\r\n\t\r\n\r\n{code}\r\n\r\n{code:title= testHTTP.js|borderStyle=solid}\r\nvar url = \"http://www.appcelerator.com\";\r\nvar xhr = Ti.Network.createHTTPClient();\r\nxhr.onload = function(e)\r\n{\r\n console.log('succes');\r\n xhr = null;\r\n};\r\nxhr.onerror = function(e)\r\n{\r\n console.log('error');\r\n xhr = null;\r\n};\r\nxhr.open(\"GET\", url);\r\nxhr.send();\r\n\r\nfunction close()\r\n{\r\n $.container.close();\r\n}\r\n\r\nvar topView = $.getView();\r\nfor (var i=0;i<300;i++)\r\n{\r\n topView.add(\r\n $.UI.create('Label',{\r\n text:'Test label '+i,\r\n top:5,\r\n color:'#fff',\r\n font:{fontSize: '10'}\r\n })\r\n );\r\n}\r\n{code}\r\n\r\nTo test open the testHTTP window many times and watch how objects increase. In Android Monitor press \"Cause GC\" from time to time. Waiting to see if the automatic GC picks it up does not make a difference.\r\n\r\nThe example code is simple but as soon as the page opened gets more complex the number of objects/heap size increases faster and eventually leads to an app crash.\r\n\r\nNote. I've tested this on my Galaxy S3 with Android 4.3", "attachment": [], "flagged": false, "summary": "Android: Ti.Network.createHTTPClient memory leak", "creator": { "name": "andersdp", "key": "andersdp", "displayName": "Anders Dahl Pape", "active": true, "timeZone": "Europe/Berlin" }, "subtasks": [], "reporter": { "name": "andersdp", "key": "andersdp", "displayName": "Anders Dahl Pape", "active": true, "timeZone": "Europe/Berlin" }, "environment": "OS X 10.10.2, Titanium SDK 3.5.0, Alloy 1.5.1", "closedSprints": [ { "id": 1073, "state": "closed", "name": "2018 Sprint 19 SDK", "startDate": "2018-09-09T21:02:56.422Z", "endDate": "2018-09-23T21:02:00.000Z", "completeDate": "2018-09-23T22:28:10.932Z", "originBoardId": 114 }, { "id": 1058, "state": "closed", "name": "2018 Sprint 16 SDK", "startDate": "2018-07-29T22:26:06.486Z", "endDate": "2018-08-12T22:26:00.000Z", "completeDate": "2018-08-13T17:38:16.757Z", "originBoardId": 114 }, { "id": 1078, "state": "closed", "name": "2018 Sprint 20 SDK", "startDate": "2018-09-23T16:57:58.349Z", "endDate": "2018-10-07T16:57:00.000Z", "completeDate": "2018-10-07T23:31:40.476Z", "originBoardId": 114 }, { "id": 1065, "state": "closed", "name": "2016 Sprint 17 SDK", "startDate": "2018-08-13T17:39:36.846Z", "endDate": "2018-08-27T17:39:00.000Z", "completeDate": "2018-08-29T16:10:57.013Z", "originBoardId": 114 }, { "id": 1084, "state": "closed", "name": "2018 Sprint 21", "startDate": "2018-10-07T23:32:40.560Z", "endDate": "2018-10-21T23:32:00.000Z", "completeDate": "2018-10-21T23:19:05.460Z", "originBoardId": 114 }, { "id": 1070, "state": "closed", "name": "2018 Sprint 18 SDK", "startDate": "2018-08-26T16:14:35.297Z", "endDate": "2018-09-09T16:14:00.000Z", "completeDate": "2018-09-11T20:59:21.495Z", "originBoardId": 114 }, { "id": 1088, "state": "closed", "name": "2018 Sprint 22", "startDate": "2018-10-21T23:20:52.653Z", "endDate": "2018-11-04T23:20:00.000Z", "completeDate": "2018-11-04T23:29:59.423Z", "originBoardId": 114 } ], "comment": { "comments": [ { "id": "350050", "author": { "name": "ahossain", "key": "ahossain", "displayName": "Amimul Hossain", "active": false, "timeZone": "Asia/Dhaka" }, "body": "Hello, We have tested this, Seems to work fine with Ti SDK 3.5.1. and 4.0.0.Beta2, Tested with Android 4.4.4- Note 3", "updateAuthor": { "name": "ahossain", "key": "ahossain", "displayName": "Amimul Hossain", "active": false, "timeZone": "Asia/Dhaka" }, "created": "2015-04-19T10:26:55.000+0000", "updated": "2015-04-19T10:26:55.000+0000" }, { "id": "356512", "author": { "name": "andersdp", "key": "andersdp", "displayName": "Anders Dahl Pape", "active": true, "timeZone": "Europe/Berlin" }, "body": "I'm still seeing the issue using Ti SDK 4.0. Tested in both simulator (4.3) and an S3 (with 4.3) and S4 (with 4.4.2)\r\n\r\nFurthermore if I use this module i'm seeing a drop in objects left behind: https://github.com/ajwhite/titanium-okhttp plus a nice speed increase. \r\n\r\nI still think theres something wonky on Android.", "updateAuthor": { "name": "andersdp", "key": "andersdp", "displayName": "Anders Dahl Pape", "active": true, "timeZone": "Europe/Berlin" }, "created": "2015-07-01T07:44:18.000+0000", "updated": "2015-07-01T07:44:18.000+0000" }, { "id": "356565", "author": { "name": "rtlechuga", "key": "rtlechuga", "displayName": "Radamantis Torres-Lechuga", "active": false, "timeZone": "Asia/Dubai" }, "body": "[~andersdp] we can not replicate, can you please send us exact steps to reproduce the issue and some more info?", "updateAuthor": { "name": "rtlechuga", "key": "rtlechuga", "displayName": "Radamantis Torres-Lechuga", "active": false, "timeZone": "Asia/Dubai" }, "created": "2015-07-01T16:50:37.000+0000", "updated": "2015-07-01T16:50:37.000+0000" }, { "id": "356973", "author": { "name": "andersdp", "key": "andersdp", "displayName": "Anders Dahl Pape", "active": true, "timeZone": "Europe/Berlin" }, "body": "I have added some code to the example above. In the testHTTP.js I have made a loop thats adds 300 labels to the window being opened which makes it clearer that something is left behind when the window closes after the Ti.Network.createHTTPClient has been run.\r\n\r\nTo make it more clear what i'm seeing I have made a youtube video for you. The video has three parts:\r\n1. I open the window 25 times, add a label 300 times and then close the window.\r\n2. I open the window 25 times, add a label 300 times, open the Ti HTTPclient and then close the window.\r\n3. I open the window 25 times, add a label 300 times, open a network connection with the https://github.com/ajwhite/titanium-okhttp Titanium OkHttp module.\r\n\r\nAs the video shows only the Ti HTTPclient leaves a lot of objects behind which never disappears.\r\n\r\nThe video can be seen here: https://www.youtube.com/watch?v=tPpyeVB1Vgc \r\n\r\nI really hope you are able to see the issue now. I have had another developer try it out and he sees it as well.", "updateAuthor": { "name": "andersdp", "key": "andersdp", "displayName": "Anders Dahl Pape", "active": true, "timeZone": "Europe/Berlin" }, "created": "2015-07-06T12:31:56.000+0000", "updated": "2015-07-06T12:31:56.000+0000" }, { "id": "358064", "author": { "name": "jonasfunk", "key": "jonasfunk", "displayName": "Jonas Funk Johannessen", "active": true, "timeZone": "America/Los_Angeles" }, "body": "Hi guys, any update on this issue? I am seeing this leak as well. ", "updateAuthor": { "name": "jonasfunk", "key": "jonasfunk", "displayName": "Jonas Funk Johannessen", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2015-07-21T11:20:23.000+0000", "updated": "2015-07-21T11:20:23.000+0000" }, { "id": "361712", "author": { "name": "andersdp", "key": "andersdp", "displayName": "Anders Dahl Pape", "active": true, "timeZone": "Europe/Berlin" }, "body": "Any news on this issue?", "updateAuthor": { "name": "andersdp", "key": "andersdp", "displayName": "Anders Dahl Pape", "active": true, "timeZone": "Europe/Berlin" }, "created": "2015-08-31T07:28:25.000+0000", "updated": "2015-08-31T07:28:25.000+0000" }, { "id": "361769", "author": { "name": "timpoulsen", "key": "timpoulsen", "displayName": "Tim Poulsen", "active": true, "timeZone": "America/Havana" }, "body": "As written, you have a problem with controller caching confusing the situation. Alloy's controllers are CommonJS modules, thus module variables, such as {{xhr}} are preserved and reused. Reusing an XHR object is not recommended. Here's a Classic app version:\r\n\r\nh3. app.js\r\n{code}\r\nvar win = Titanium.UI.createWindow({\r\n\ttitle: 'Tab 1',\r\n\tbackgroundColor: '#fff'\r\n});\r\nvar label = Titanium.UI.createLabel({\r\n\tcolor: '#000',\r\n\ttext: 'Click me',\r\n\ttextAlign: 'center'\r\n});\r\n\r\nlabel.addEventListener('click', function () {\r\n\trequire('netwin').open({\r\n\t\tmodal: true\r\n\t});\r\n});\r\nwin.add(label);\r\n\r\nwin.open();\r\n{code}\r\n\r\nh3. netwin.js\r\n{code}\r\nvar Netwindow = function () {\r\n\tvar netwin = Titanium.UI.createWindow({\r\n\t\ttitle: 'Tab 1',\r\n\t\tbackgroundColor: '#000'\r\n\t});\r\n\tvar label = Titanium.UI.createLabel({\r\n\t\tcolor: '#fff',\r\n\t\ttext: 'Click me to close',\r\n\t\ttextAlign: 'center'\r\n\t});\r\n\r\n\tlabel.addEventListener('click', function () {\r\n\t\tnetwin.close();\r\n\t});\r\n\tnetwin.add(label);\r\n\r\n\tnetwin.addEventListener('open', function () {\r\n\t\tvar xhr = Ti.Network.createHTTPClient(),\r\n\t\t\turl = 'http://www.google.com';\r\n\t\txhr.onload = function (e) {\r\n\t\t\tconsole.log('success');\r\n\t\t\txhr = null;\r\n\t\t};\r\n\t\txhr.onerror = function (e) {\r\n\t\t\tconsole.log('error');\r\n\t\t\txhr = null;\r\n\t\t};\r\n\t\txhr.open(\"GET\", url);\r\n\t\txhr.send();\r\n\t});\r\n\r\n\treturn netwin;\r\n\r\n};\r\n\r\nmodule.exports = new Netwindow();\r\n{code}\r\n\r\nMake sure you have the following in your manifest in tiapp.xml:\r\n\r\n{code}\r\n\r\n{code}\r\n\r\nFollowing these steps, I don't think I'm seeing a leak. Testing on device, using Monitor's Allocation Tracker tab, I open the app then in Monitor click Start Tracking. In the app, tap \"Click Me.\" In Monitor, in the filter box, enter {{http}}, then click Get Allocations and a bunch of objects will be listed. In the app, tap \"Click me to close\" then click Get Allocations again. I see nothing listed. Repeat as desired, and I still see no objects listed when the child window is closed. This would indicate to me that all HTTP-related objects are being released.\r\n\r\nIn an Alloy app, I would use the open event listener technique as I show in the code above so that all your variables are encapsulated within a function and disposed of at the end of that function's invocation.", "updateAuthor": { "name": "timpoulsen", "key": "timpoulsen", "displayName": "Tim Poulsen", "active": true, "timeZone": "America/Havana" }, "created": "2015-08-31T13:00:55.000+0000", "updated": "2015-08-31T13:00:55.000+0000" }, { "id": "361772", "author": { "name": "andersdp", "key": "andersdp", "displayName": "Anders Dahl Pape", "active": true, "timeZone": "Europe/Berlin" }, "body": "Thanks for your time, Tim!\r\n\r\nJust a quick reply for now (I'm heading out).\r\n\r\nUsing the exact same code in my example but using the https://github.com/ajwhite/titanium-okhttp module instead of TiHTTP I see no objects left behind. As far as I know the OK http module uses a newer version of the http library. If it was a problem with my code the problem should persist? I'm not saying it's not my coding but I'm just trying to understand.", "updateAuthor": { "name": "andersdp", "key": "andersdp", "displayName": "Anders Dahl Pape", "active": true, "timeZone": "Europe/Berlin" }, "created": "2015-08-31T13:42:16.000+0000", "updated": "2015-08-31T18:25:48.000+0000" }, { "id": "361837", "author": { "name": "timpoulsen", "key": "timpoulsen", "displayName": "Tim Poulsen", "active": true, "timeZone": "America/Havana" }, "body": "The okhttp module may not have the same troubles with reusing objects like the Titanium HttpClient object has. I'm pretty sure Appc has gotten rid of the Apache HTTP code in the newest versions. You might want to try with one of the newer SDKs. ", "updateAuthor": { "name": "timpoulsen", "key": "timpoulsen", "displayName": "Tim Poulsen", "active": true, "timeZone": "America/Havana" }, "created": "2015-08-31T22:18:47.000+0000", "updated": "2015-08-31T22:18:47.000+0000" }, { "id": "361904", "author": { "name": "andersdp", "key": "andersdp", "displayName": "Anders Dahl Pape", "active": true, "timeZone": "Europe/Berlin" }, "body": "Sounds interesting about the dropped apache http code. I'm already on the latest stable AppC SDK - could it be in some beta?", "updateAuthor": { "name": "andersdp", "key": "andersdp", "displayName": "Anders Dahl Pape", "active": true, "timeZone": "Europe/Berlin" }, "created": "2015-09-01T07:56:45.000+0000", "updated": "2015-09-01T08:20:20.000+0000" }, { "id": "361929", "author": { "name": "andersdp", "key": "andersdp", "displayName": "Anders Dahl Pape", "active": true, "timeZone": "Europe/Berlin" }, "body": "Found some info in the 4.1 GA release notes. I've been using 4.0 recently. Will test it out to see if something has changed.", "updateAuthor": { "name": "andersdp", "key": "andersdp", "displayName": "Anders Dahl Pape", "active": true, "timeZone": "Europe/Berlin" }, "created": "2015-09-01T12:19:31.000+0000", "updated": "2015-09-01T12:19:48.000+0000" }, { "id": "361972", "author": { "name": "fokkezb", "key": "fokke", "displayName": "Fokke Zandbergen", "active": true, "timeZone": "Europe/Amsterdam" }, "body": "[~andersdp] 5.0 (release this month) will no longer use Apache HTTP and will probably solve this issue.", "updateAuthor": { "name": "fokkezb", "key": "fokke", "displayName": "Fokke Zandbergen", "active": true, "timeZone": "Europe/Amsterdam" }, "created": "2015-09-01T19:45:20.000+0000", "updated": "2015-09-01T19:45:20.000+0000" }, { "id": "362064", "author": { "name": "andersdp", "key": "andersdp", "displayName": "Anders Dahl Pape", "active": true, "timeZone": "Europe/Berlin" }, "body": "Sounds great @Fokke", "updateAuthor": { "name": "andersdp", "key": "andersdp", "displayName": "Anders Dahl Pape", "active": true, "timeZone": "Europe/Berlin" }, "created": "2015-09-02T12:04:27.000+0000", "updated": "2015-09-02T12:04:38.000+0000" }, { "id": "362460", "author": { "name": "jonasfunk", "key": "jonasfunk", "displayName": "Jonas Funk Johannessen", "active": true, "timeZone": "America/Los_Angeles" }, "body": "Haven't tried the 5.0 beta just yet but here is nothing in the release notes for 5.0 that indicate a change in the http code. Is it safe to assume it hasn't been updated, or are the release notes incomplete?", "updateAuthor": { "name": "jonasfunk", "key": "jonasfunk", "displayName": "Jonas Funk Johannessen", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2015-09-07T19:27:27.000+0000", "updated": "2015-09-07T19:27:27.000+0000" }, { "id": "362487", "author": { "name": "fokkezb", "key": "fokke", "displayName": "Fokke Zandbergen", "active": true, "timeZone": "Europe/Amsterdam" }, "body": "[~jonasfunk] it has been merged to master before 5.0.0 was branched so it is in 5.0. I will ask for the release notes to reflect that.\r\nhttps://github.com/appcelerator/titanium_mobile/pull/7036", "updateAuthor": { "name": "fokkezb", "key": "fokke", "displayName": "Fokke Zandbergen", "active": true, "timeZone": "Europe/Amsterdam" }, "created": "2015-09-08T07:49:58.000+0000", "updated": "2015-09-08T07:49:58.000+0000" }, { "id": "369132", "author": { "name": "jonasfunk", "key": "jonasfunk", "displayName": "Jonas Funk Johannessen", "active": true, "timeZone": "America/Los_Angeles" }, "body": "Ran this scenario again with the attached test case. From a baseline of 78.000 objects, using 5.1 beta http-client, Monitor reaches approx. 500.000 objects (422.000 unreleased objects ), while https://github.com/ajwhite/titanium-okhttp module leaves just 100.000 objects (22.000 unreleased objects!). There is obviously still an issue here.", "updateAuthor": { "name": "jonasfunk", "key": "jonasfunk", "displayName": "Jonas Funk Johannessen", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2015-11-05T22:59:09.000+0000", "updated": "2015-11-05T22:59:09.000+0000" } ], "maxResults": 23, "total": 23, "startAt": 0 } } }