{ "id": "80545", "key": "TIMOB-5352", "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": [ { "id": "12078", "description": "", "name": "Sprint 2011-38", "archived": true, "released": true, "releaseDate": "2011-09-26" }, { "id": "11331", "description": "", "name": "Release 1.8.0", "archived": true, "released": true, "releaseDate": "2011-10-31" } ], "resolution": { "id": "1", "description": "A fix for this issue is checked into the tree and tested.", "name": "Fixed" }, "resolutiondate": "2011-11-22T11:12:40.000+0000", "created": "2011-09-23T02:55:26.000+0000", "priority": { "name": "Critical", "id": "1" }, "labels": [ "branch-5062", "module_imageview", "qe-testadded" ], "versions": [ { "id": "11570", "description": "", "name": "Release 1.7.2", "archived": true, "released": true, "releaseDate": "2011-07-21" } ], "issuelinks": [], "assignee": { "name": "stephentramer", "key": "stephentramer", "displayName": "Stephen Tramer", "active": true, "timeZone": "America/Los_Angeles" }, "updated": "2011-11-22T11:12:40.000+0000", "status": { "description": "The issue is considered finished, the resolution is correct. Issues which are closed can be reopened.", "name": "Closed", "id": "6", "statusCategory": { "id": 3, "key": "done", "colorName": "green", "name": "Done" } }, "components": [ { "id": "10206", "name": "iOS", "description": "iOS Platform" } ], "description": "Extensive stress on the system of loading local images can lead to memory warnings and jetsam purges. This is easily demonstrated by constantly setting a badge on an icon which uses a custom image (setting a badge refreshes the tab, which reloads the image). The best way to see this effect cascade is by tying available memory to the badge value via a timer, which will force repeated refreshes.\r\n\r\nSAMPLE APP\r\n----\r\n{code:title=app.js}\r\nTitanium.UI.setBackgroundColor('#000');\r\nvar tabGroup = Titanium.UI.createTabGroup({id:'tabGroup1'});\r\nvar win1 = Titanium.UI.createWindow({backgroundColor:'white'});\r\n\r\nvar tab1 = Titanium.UI.createTab({\r\n\ticon:'bug.png',\r\n\twindow:win1\r\n});\r\nsetInterval(function() { \r\n\ttab1.badge = parseInt(Ti.Platform.availableMemory);\r\n}, 50);\r\ntabGroup.addTab(tab1);\r\ntabGroup.open();\r\n\r\n{code}\r\n\r\nIdeally, this will be run on device since it is more memory-constrained and jetsam will kill the app. Do NOT fix the side-effects of the caching problem (namely, that tabs are reloaded in this manner).\r\n\r\nTESTING\r\n----\r\nThe bug is not fixed as long as the badge number on the app goes down. This app is specifically designed to not allocate additional memory beyond the occasional autoreleased value. jetsam won't necessarily terminate, and you may need to watch the app for an extended period of time (several minutes) before seeing decreases of the magnitude that will lead to the badge number fluctuating (indicating allocation/reclamation) or plummeting.", "attachment": [ { "id": "23039", "filename": "bug.png", "author": { "name": "stephentramer", "key": "stephentramer", "displayName": "Stephen Tramer", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2011-09-23T02:55:26.000+0000", "size": 3297, "mimeType": "image/png" }, { "id": "23048", "filename": "localloader.js", "author": { "name": "stephentramer", "key": "stephentramer", "displayName": "Stephen Tramer", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2011-09-24T05:52:48.000+0000", "size": 1804, "mimeType": "application/x-javascript" }, { "id": "23047", "filename": "remoteloader.js", "author": { "name": "stephentramer", "key": "stephentramer", "displayName": "Stephen Tramer", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2011-09-24T05:50:25.000+0000", "size": 1418, "mimeType": "application/x-javascript" } ], "flagged": false, "summary": "iOS: Turn on local caching for images", "creator": { "name": "stephentramer", "key": "stephentramer", "displayName": "Stephen Tramer", "active": true, "timeZone": "America/Los_Angeles" }, "subtasks": [], "reporter": { "name": "stephentramer", "key": "stephentramer", "displayName": "Stephen Tramer", "active": true, "timeZone": "America/Los_Angeles" }, "environment": null, "comment": { "comments": [ { "id": "166724", "author": { "name": "dtoth", "key": "dtoth", "displayName": "Dawson Toth", "active": true, "timeZone": "America/New_York" }, "body": "Added the branch-5062 label.", "updateAuthor": { "name": "dtoth", "key": "dtoth", "displayName": "Dawson Toth", "active": true, "timeZone": "America/New_York" }, "created": "2011-09-23T04:27:32.000+0000", "updated": "2011-09-23T04:27:32.000+0000" }, { "id": "166740", "author": { "name": "dtoth", "key": "dtoth", "displayName": "Dawson Toth", "active": true, "timeZone": "America/New_York" }, "body": "I've created a very stressful app.js for you to test caching of local images. The following will download a remote image, and then progressively copy it out to disk until it reaches numberOfLocalImages (a variable at the top of the app.js). Then it will just repeatedly load those images in, for the rest of eternity.\r\n\r\nTested with 1.8.0 master, and confirmed that memory leaks and the app will crash. In this case, it will crash very quickly. Enjoy!\r\n\r\nversion=1.8.0\r\ntimestamp=09/06/11 10:54\r\ngithash=2888f72...\r\n\r\n{code:title=app.js}\r\nvar initialImage = 'http://appc.me/content/kitten.jpg';\r\nvar numberOfLocalImages = 20;\r\nvar fileName = 'kitten';\r\nvar fileExtension = '.jpg';\r\n\r\nvar win = Ti.UI.createWindow({\r\n backgroundColor: '#fff'\r\n});\r\n\r\nvar iterationCount = Ti.UI.createLabel({\r\n text: 'Iteration: Loading...', textAlign: 'center',\r\n bottom: 0, left: 0,\r\n height: 30, width: '50%',\r\n color: '#fff', backgroundColor: '#000'\r\n});\r\nwin.add(iterationCount);\r\nvar freeMemory = Ti.UI.createLabel({\r\n text: 'Free Memory: Loading...', textAlign: 'center',\r\n right: 0, bottom: 0,\r\n height: 30, width: '50%',\r\n color: '#fff', backgroundColor: '#000'\r\n});\r\nwin.add(freeMemory);\r\nsetInterval(function() {\r\n iterationCount.text = 'Iteration Count: ' + (currentImage % numberOfLocalImages) \r\n + ' (Total: ' + currentImage + ')';\r\n freeMemory.text = 'Free Memory: ' + Ti.Platform.availableMemory;\r\n}, 100);\r\n\r\nvar currentImage = 0;\r\nvar imageView = Ti.UI.createImageView({\r\n image: initialImage,\r\n bottom: 30\r\n});\r\nimageView.addEventListener('load', function() {\r\n var file = Ti.Filesystem.getFile(\r\n Ti.Filesystem.applicationDataDirectory,\r\n fileName + (currentImage % 200) + fileExtension);\r\n if (!file.exists()) {\r\n file.write(imageView.toImage());\r\n }\r\n imageView.image = file.nativePath;\r\n currentImage += 1;\r\n});\r\n\r\nwin.add(imageView);\r\n\r\nwin.open();\r\n{code}", "updateAuthor": { "name": "dtoth", "key": "dtoth", "displayName": "Dawson Toth", "active": true, "timeZone": "America/New_York" }, "created": "2011-09-23T08:51:04.000+0000", "updated": "2011-09-23T08:51:04.000+0000" }, { "id": "166741", "author": { "name": "dtoth", "key": "dtoth", "displayName": "Dawson Toth", "active": true, "timeZone": "America/New_York" }, "body": "And here is a remote version of the above. This one seems to stabilize, so remote caching probably works (*shrug*):\r\n\r\n{code:title=app.js}\r\nvar imagePrefix = 'http://photosbydawson.com/photos/4e4f53911b9ba916d0b386c4/_MG_';\r\nvar imageSuffix = '.480x320.jpg';\r\nvar numberOfImages = 20;\r\n\r\nvar win = Ti.UI.createWindow({\r\n backgroundColor: '#fff'\r\n});\r\n\r\nvar iterationCount = Ti.UI.createLabel({\r\n text: 'Iteration: Loading...', textAlign: 'center',\r\n bottom: 0, left: 0,\r\n height: 30, width: '50%',\r\n color: '#fff', backgroundColor: '#000'\r\n});\r\nwin.add(iterationCount);\r\nvar freeMemory = Ti.UI.createLabel({\r\n text: 'Free Memory: Loading...', textAlign: 'center',\r\n right: 0, bottom: 0,\r\n height: 30, width: '50%',\r\n color: '#fff', backgroundColor: '#000'\r\n});\r\nwin.add(freeMemory);\r\n\r\nvar currentImage = 0;\r\nvar imageView = Ti.UI.createImageView({\r\n image: imagePrefix + currentImage + imageSuffix,\r\n bottom: 30\r\n});\r\nsetInterval(function() {\r\n currentImage += 1;\r\n iterationCount.text = 'Iteration Count: ' + (currentImage % numberOfImages)\r\n + ' (Total: ' + currentImage + ')';\r\n freeMemory.text = 'Free Memory: ' + Ti.Platform.availableMemory;\r\n Ti.API.info('loading ' + imagePrefix + (currentImage % numberOfImages) + imageSuffix);\r\n imageView.image = imagePrefix + (currentImage % numberOfImages) + imageSuffix;\r\n}, 1000);\r\nwin.add(imageView);\r\n\r\nwin.open();\r\n{code}", "updateAuthor": { "name": "dtoth", "key": "dtoth", "displayName": "Dawson Toth", "active": true, "timeZone": "America/New_York" }, "created": "2011-09-23T08:59:13.000+0000", "updated": "2011-09-23T08:59:13.000+0000" }, { "id": "166866", "author": { "name": "stephentramer", "key": "stephentramer", "displayName": "Stephen Tramer", "active": true, "timeZone": "America/Los_Angeles" }, "body": "Test for remote image loading (remoteloader.js). This test passes when:\n\n- Memory stabilizes eventually\n- Suspending/resuming app does not disrupt the changing of the image view (and memory is stable)\n- After force-terminating the app (but not reinstalling), images do not download; they load from disk (rapid redisplay, low latency, etc.)", "updateAuthor": { "name": "stephentramer", "key": "stephentramer", "displayName": "Stephen Tramer", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2011-09-24T05:50:25.000+0000", "updated": "2011-09-24T05:50:25.000+0000" }, { "id": "166867", "author": { "name": "stephentramer", "key": "stephentramer", "displayName": "Stephen Tramer", "active": true, "timeZone": "America/Los_Angeles" }, "body": "Test for local image loading (localloader.js) - more strenuous than the initial test submitted. For this test to pass:\n\n- Memory should eventually stabilize (but may be VERY LOW on device - this image is 205k!)\n- Forcing a memory panic should bring memory usage down significantly (on simulator); turn on DEBUG_IMAGE_CACHE and look for the \"pages freed\" message. Memory panics on device (if they occur) should also free up a large amount of space.\n\nNote that the initial image IS downloaded from a remote source, so have a fast connection available (otherwise the image download will time out).", "updateAuthor": { "name": "stephentramer", "key": "stephentramer", "displayName": "Stephen Tramer", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2011-09-24T05:52:48.000+0000", "updated": "2011-09-24T05:52:48.000+0000" }, { "id": "166870", "author": { "name": "rseagraves", "key": "rseagraves", "displayName": "Reggie Seagraves", "active": true, "timeZone": "America/Los_Angeles" }, "body": "Merged in typo fix from pull request #495.", "updateAuthor": { "name": "rseagraves", "key": "rseagraves", "displayName": "Reggie Seagraves", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2011-09-24T14:28:54.000+0000", "updated": "2011-09-24T14:29:05.000+0000" }, { "id": "172846", "author": { "name": "nhuynh", "key": "nhuynh", "displayName": "Natalie Huynh", "active": true, "timeZone": "America/Los_Angeles" }, "body": "Pass: Tested with 1.8.0.1.v20111114102656 on\r\niPad 2 4.3.5\r\niPhone 4s 5.0\r\niPod 3g 4.0.2", "updateAuthor": { "name": "nhuynh", "key": "nhuynh", "displayName": "Natalie Huynh", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2011-11-15T16:30:45.000+0000", "updated": "2011-11-15T16:30:45.000+0000" }, { "id": "173742", "author": { "name": "nhuynh", "key": "nhuynh", "displayName": "Natalie Huynh", "active": true, "timeZone": "America/Los_Angeles" }, "body": "Open to add tag", "updateAuthor": { "name": "nhuynh", "key": "nhuynh", "displayName": "Natalie Huynh", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2011-11-22T11:12:28.000+0000", "updated": "2011-11-22T11:12:28.000+0000" } ], "maxResults": 9, "total": 9, "startAt": 0 } } }