29

Our app's home screen (and therefore the first seen by all users) has several sections, most of which contain diferent webviews the user may want to open. Doing so increases memory usage from barely 26MB to up to 85MB or even more (after opening all diferent webviews).

The problem we found is that, once they're closed, all web page resources seem to be kept at memory (used memory barely decreases a couple of MB perhaps).

I would like to free the resources the webview had to open because, later on, there's a very demanding section of our app which needs a lot of memory and completely crashes the app if you happen to have been browsing through several of those webviews before.

I have found several options on the internet to try but none of them have worked so far. Things such as:

// Try to clean used webview

[self.webView loadHTMLString:@"" baseURL:nil];
[self.webView stopLoading];
self.webView.delegate = nil;
[self.webView removeFromSuperview];
self.webView = nil;

They've made absolutely almost no effect on memory usage. Is there anything I'm missing here? I already double checked that I have no leaks that would keep the WebView opened, I'm already freeing the only reference to it that I have (self.webView = nil;)

Edit: I just created a project from scratch, added a webview and a button which loads a different web every time I click it, which in turn increases memory usage. I also added a button that will destroy the webview when clicked and, guess what, memory stays the same, like it's effectively not releasing any resources.

h4lc0n
  • 2,730
  • 5
  • 29
  • 41
  • Are you using ARC ? If you are not using ARC than you need to call release on your web view. – Ankush Jan 16 '14 at 12:19
  • @Ankush yes, I am, thanks anyways – h4lc0n Jan 16 '14 at 12:22
  • 1
    Maybe I misunderstood the nature of your question but I'd like to propose to change the controller architecture to have just one UIWebView instance, this is really heavyweight but very expressive and self-contained user element. You can add some server proxy/aggregator which feeds all your widgets in this web view. Later you could catch javascript events and apply your logic – voromax Jan 16 '14 at 12:29
  • @voromax Yes, I had that idea in mind as well. I wanted to create a blank project and play with webviews to see if that would fix the problem. I still think there should be a way to clear whatever resources a webview had to use, though, considering how it's (or should) no longer available. Thanks for your contribution – h4lc0n Jan 16 '14 at 13:47

3 Answers3

19

It's been several months since I asked this question and it seems no one knows any work around, so I'm just answering myself to give it some closure and, sadly, bad news to whoever is having this same issue.

We kept trying to fight this issue for several days and, after talking to some people who somehow hinted us that we had nothing to do about it (it's just a different process taking care of everything to which we have no access), we decided to restrict the webview access to custom made pages.

For example, we had a news sections which opened webs on the internet. What we ended up doing was open custom-made web pages which contained the title, body and an image related to the news (which still adds to resource memory usage, but we managed to keep it in a contained small format which would need thousands of news to be opened to be of any danger). I know, not ideal.

I'd still love to see some constructive answers to this question, whether it's a solution, a workaround, or any idea that can help future users with this same issue have clues on how to deal with it.

h4lc0n
  • 2,730
  • 5
  • 29
  • 41
  • I have same issue when load many images in UIWebView, i have search but not find really solution. When content load into UIWebView it increase memory and not release until refresh/reopen App. – Hanh Le May 24 '14 at 01:24
  • I have this issue too. Really bad that nothing can be done about it. I only have one web view but with video. I've tried everything that is recommended here on SO and the memory just keeps building up. Eventually, after watching lots of videos, the app falls over and terminates. :( – BlueVoodoo Jun 02 '14 at 15:04
  • Did you ever find out anything more about this? I'm definitely seeing the exact same behavior. After viewing URLs the memory continues to load until eventually the app will crash. I've done everything I've seen so far on the web but I'm keeping my fingers crossed there's something I've missed out there.... – George Clingerman Jun 05 '14 at 22:56
  • @GeorgeClingerman I'm afraid not... I really hope Apple someday realizes they should give a way for users to release WebViews' inner resources. – h4lc0n Jun 06 '14 at 09:37
  • 2
    God damnit, just hit this wall as well. Seriously, Apple, are you serious? – AlBirdie Aug 20 '15 at 17:33
7

you should read this article from Jason Baker,

http://www.codercowboy.com/code-uiwebview-memory-leak-prevention/

He has created a category which really helped me to redue memory footprint of UIWebView.

you just have to call two lines after adding category

-(void) dealloc
{

    [self.webview cleanForDealloc];
    self.webview = nil;
    [super dealloc];

}
2intor
  • 1,044
  • 1
  • 8
  • 19
  • 2
    Yes, I tried that already. That's where I got the options to try from but it didn't really work. I'll give it another go with a clean project to see if that makes things different. Thanks – h4lc0n Jan 16 '14 at 13:51
1
override func viewWillDisappear(_ animated: Bool) {
    super.viewWillDisappear(animated)
    categoryWebView.stopLoading()
    categoryWebView.removeFromSuperview()
    categoryWebView = nil

    URLCache.shared.removeAllCachedResponses()
    URLCache.shared.diskCapacity = 0
    URLCache.shared.memoryCapacity = 0
    if let cookies = HTTPCookieStorage.shared.cookies {
        for cookie in cookies {
            HTTPCookieStorage.shared.deleteCookie(cookie)
        }
    }
}
Sachin Kishore
  • 324
  • 3
  • 8