16

在我们系统的其他地方寻找内存泄漏,我创建了一个带有元刷新标签的 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 文档关闭。

我还尝试编写递归 removeFromSuperview 和 removeFromParentViewController,读到 webview 中的私有滚动视图是内存问题,但该内存永远不会被释放。当我们完成它时,我似乎找不到一种可靠的方法来关闭、解除 web 视图。

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

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

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

4

4 回答 4

21

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

- (void) viewWillDisappear:(BOOL)animated {
    if (self.isMovingFromParentViewController) {
        [self.wv loadHTMLString: @"" baseURL: nil];
    }
}
于 2013-05-13T02:59:00.867 回答
10

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

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

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

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

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    [myWebView reload];
}
于 2013-10-26T16:48:45.437 回答
2

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

Apple 的 WKWebView 类参考

WKWebView 上的 nshipster

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

WKWebViewTips

于 2015-02-18T14:59:14.553 回答
-1
  • 削弱积木中的“自我”。

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

于 2014-11-25T05:52:41.953 回答