[TIMOB-3071] iOS: WebView memory is not freed
GitHub Issue | n/a |
---|---|
Type | Bug |
Priority | High |
Status | Closed |
Resolution | Fixed |
Resolution Date | 2012-04-03T08:35:50.000+0000 |
Affected Version/s | n/a |
Fix Version/s | Sprint 2012-05, Release 2.0.0, Release 1.8.3 |
Components | iOS |
Labels | klist, memory, module_webview, qe-testadded |
Reporter | Pedro Enrique |
Assignee | Blain Hamon |
Created | 2011-04-15T03:35:59.000+0000 |
Updated | 2012-04-03T08:40:13.000+0000 |
Description
When replacing HTML elements in a webView, large images for example, the memory used by the previous element is not release causing an overall memory usage by the webView to rise every time.
There is a HD ticket with a sample code:
http://developer.appcelerator.com/helpdesk/view/70741">http://developer.appcelerator.com/helpdesk/view/70741
Tested on Ti SDK 1.6 (Feb 7 2011 11:29 r160f5dc)
iPhone Simulator with Xcode's Instruments Tools
Attachments
File | Date | Size |
---|---|---|
webtoll.zip | 2011-04-15T03:36:00.000+0000 | 24361 |
Even MORE memory madness...
Unfortunately, this is not something we have control over. I even tested in a native app outside of Titanium, and the web view's memory footprint is its own thing. There's no API on web views for controlling memory. Worse yet, NSURLCache, which the docs implies the web views would use, was not used at all, so there was nothing to cache.
Thanks for looking into it. IIRC I can't work around this by creating a new webview at the moment, because the webview memory is not freed when the JS object is deleted. Is this something that will be addressed in 1.7?
There have been quite a few memory circular retains that have been fixed for 1.7, and you'll see this most when you have a lot of non-web views and the like, especially with addEventListener. However, while the webview itself is released, the caching itself is not kept to the web view, but follows the beat of a different drummer.
Included is the test app I made. It is all native Obj-C, no titanium, to make sure it wasn't just an artifact of Titanium. It simply is a viewcontroller (similar to a Ti.UI.window) with a web view, and two buttons: One button to open up another view controller with a web view, another to try to purge the NSURLCache.
If you play with this with the allocations monitor on it, you'll see the memory jump around, sometimes almost of its own accord. One thing you'll notice is the memory behavior is quite different on simulator as opposed to on device, especially the footprint of webkit. Hitting the back does free up some memory, but not as much or as predictably as you expect. Worse yet, this memory size is completely unaffected by the Cache button.
That's disappointing news, but I understand it's not Titanium's fault, and appreciate you investigating. I wonder if http://blog.techno-barje.fr/post/2010/10/04/UIWebView-secrets-part1-memory-leaks-on-xmlhttprequest"> http://blog.techno-barje.fr/post/2010/10/04/UIWebView-secrets-part1... is at all related?
"WebKitCacheModelPreferenceKey"? Innnnteresting. I'll see what I can do with this, and more importantly, if Apple considers it private API or not. (You'd think something like a string wouldn't trip them off, but a long while ago, they claimed a well-documented POSIX string library that's been around since the 80s was 'private API'.)
Okay, an update. I didn't see much of a change in setting that key, as in it still grows as it desires, although it did seem like it might be more conservative in grabbing memory.
Either way, the NSUserDefaults is exposed in Titanium as Ti.App.properties. So to recreate the solution proposed, use the following JS in your app.js (NOT in the web page):
Titanium.App.Properties.setInt('WebKitCacheModelPreferenceKey',0);
I don't know if setting that NSUserDefault will help things, but it at least is a means to try it. Good luck.
Thanks for trying it. I'm really busy at the moment and won't have time to play around with the code you provided for a while as I really need to learn some more objC first, but I appreciate you providing it, and do plan to return to this issue when I have a chance.
Due diligence has been performed and we're placing this on hold as an Apple bug. Will redress for 1.8.
Talked with Alan. Turns out this might be about something different. {quote} alanleard: bhamon: what they are trying to do is create a webview, load a sencha chart, do a toImage, and then remove the webview. They are nulling it, removing it, we can't find any references to it, but they still get retained bhamon: Okay, that's different than what I thought they wanted. If you can update the ticket with sample code, or a minimum fail case, then here's the possibilities: 1) We're leaking the UIWebView or the proxy. That CAN be fixed. 2) The HTML and images are still being cached by Apple, despite the UIWebView having gone away. That CANNOT be fixed. I was thinking they were talking about the latter, not the former. {quote}
Okay, verified. The leak DOES happen in 1.8.2GA, but does NOT happen in CI (As of March 6th) so we're going to mark this fixed, since it has been fixed, possibly as a side-effect of some other commit, and will be in 1.9.
Closing bug. Verified TiUIWebView object is being released on: SDK build: 2.0.0.v20120307090205 Titanium Studio, build: 1.0.9.201202141208 xcode: 4.2 Device: iphone 3GS (4.3)
Reopening to place the Release 1.8.3 tag