ios UIWebView中的大量内存泄漏

Posted

技术标签:

【中文标题】ios UIWebView中的大量内存泄漏【英文标题】:massive memory leak in ios UIWebView 【发布时间】:2013-05-07 00:36:21 【问题描述】:

在我们系统的其他地方寻找内存泄漏,我创建了一个带有元刷新标签的 20 MB 网页。这个想法是通过我们的数据路径代码移动大量数据以确认内存稳定性。

<html>
<meta http-equiv="refresh" content="1">
<body>
<div style="border: 1px solid red">
    Content loading
</div><!-- 20mb worth of comments -->
</body>
</html>

我发现 uiwebview 显示元刷新页面非常非常快地泄漏内存。应用程序内存在大约 2 分钟内达到 300mb,并收到内存不足警告,即使我们的代码没有运行。

我已停止刷新加载并尝试解除 webview 的分配。

我试过 loadurl:"about:blank", loadhtml:"", javascript document close.

我还尝试编写递归 removeFromSuperview 和 removeFromParentViewController,读到 webview 中的私有滚动视图是内存问题,但该内存从未释放。我似乎无法找到一种可靠的方法来关闭,在我们完成后解除 webview 的分配。

很长一段时间以来,我们一直生活在缓慢的 webview 泄漏率中,并且真的想找到一种方法来确保在我们完成后可以完全清理 webview。我们最近将应用程序转换为 ARC,它不会改变内存速率。

我正在考虑尝试对 web 视图中的所有对象进行递归循环,看看它们是否可以被释放。对于 20MB 页面的每次刷新,instruments 都会显示 20mb 的 cfdata,但不会将它们显示为泄漏。如果我只提供响应头并完成到 urlprotocol 客户端,我们可以稳定运行,所以可以确认其余数据路径中的 memleaks,但这是一个如此戏剧性的测试用例结果,我希望能找到一次 webview 内存泄漏解决方案并为所有人。

有没有人有更好的想法,或者有没有人尝试过递归浏览 uiwebview 中的对象?

【问题讨论】:

当应用程序显示没有泄漏,但数据不断增长时,这意味着对象在某处还活着。找到它们(查看它们在工具中的保留/释放历史记录) 【参考方案1】:

我摆脱 UIWebView 内存泄漏的方法是将其 HTML 设置为空字符串。这样做的一个地方是当包含 web 视图的视图控制器消失时:

- (void) viewWillDisappear:(BOOL)animated 
    if (self.isMovingFromParentViewController) 
        [self.wv loadHTMLString: @"" baseURL: nil];
    

【讨论】:

这帮助我减少了泄漏,但并没有完全解决问题。不过,感谢您分享您的解决方案。 @Myxtic 不要忘记将 Web 视图的委托也设置为 nil。 是的,我也有,没有多大帮助。 这在我的情况下修复了内存泄漏!【参考方案2】:

对所有开发者的呼喊:在使用 UIWebView 时,实现 didReceiveMemoryWarning 是绝对必须的!

当 UIWebView 可以导航到任何地方或您知道会导致 UIWebView 出现大量泄漏的页面时,这一点尤其重要,例如 m.youtube.com。

修复漏洞的一种很好且通常无缝的方法就是重新加载页面。这样您就不必担心页面会变空,并且通常用户可以从他离开的地方继续工作。

在您的视图控制器中,像这样覆盖 didReceiveMemoryWarning:

- (void)didReceiveMemoryWarning

    [super didReceiveMemoryWarning];
    [myWebView reload];

【讨论】:

我刚试过这个。这导致 UIWebView 无法控制地重新加载多次,但未能控制内存增长。我应该更有耐心吗?【参考方案3】: 弱化块中的“自我”。

这是导致 WebView 内存即使在弹出导航堆栈时仍被占用的重要原因之一。

【讨论】:

【参考方案4】:

使用 ios 8 及更高版本,您真的很幸运。 WKWebView 不会泄漏,并且内存占用比 UIWebView 小得多。用包含复杂 Javascript 的载有图片的网页对其进行了测试,它表现良好。

Apple's WKWebView Class Reference

nshipster on WKWebView

虽然它并不完美。然后再次希望不完美的地方能及时解决。在 GitHub 上查看 Shingo Fukuyama 的提示:

WKWebViewTips

【讨论】:

这在 iOS 8 上很棒,但是我们中的许多人仍然必须支持 iOS 7。我们中的许多人都尝试了在 iOS 7 上提供的解决方案,但没有成功。非常令人沮丧 不幸的是,这不一定是真的。我不是 100% 确定在 iOS 8 上是否是这种方式,但在 iOS 9 上,wkWebView 会到处泄漏内存。对于任何决定基于此切换到 wkWebView 的人来说,这只是一个提示。参考:forums.developer.apple.com/thread/22795 和 forums.developer.apple.com/thread/21956

以上是关于ios UIWebView中的大量内存泄漏的主要内容,如果未能解决你的问题,请参考以下文章

UIWebView 是不是泄漏内存?

iPhone - 内存泄漏 - NSData dataWithContentsOfUrl & UIWebView

Java 应用程序中 io.vertx.core.impl.EventLoopContext 中的内存泄漏

iOS swift 3中的内存泄漏

iOS 或 MonoTouch 中的固有内存泄漏?

如何解决 iOS App 中的内存泄漏问题?