it seems like very old and well known problem, people are running into it since 2008 and still no solution(((( discussions.info.apple.com/thread.jspa?threadID=1729697
@adad184 简单的测试代码,这样肯定会crash,但是把load去掉的话,仅消耗2M内存
for (int i = 0; i < 40; i++)
{
UIWebView *m_webView = [[UIWebView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height)];
[m_webView setBackgroundColor:[UIColor whiteColor]];
[self.view addSubview:m_webView];
[m_webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"http://www.youku.com"]]];
}
30M?这是个很正常的数字。
大约2年前我们写第一版云彩时,就尝试了用WebView做个人空间的实现。
过程中发现2个主要的问题: 1. 浏览器滚动性能极差,相对native滚动,你基本无法忍受那种bianmi的感觉。 2. 内存无法控制释放,我当时用Instruments去调试和观察了所有object的申请和释放,去猜测所有dom树的生成规律。发现找不到可控点来清理内存。最后忍无可忍就做了翻页(webview会在加载新页面时释放上一个页面的内存)
当然,这个可能和我们加载的网页图片多有关(我的页面代码是纯手写纯css渲染的),优酷那种恐龙级别的页面自然会极大地吃掉你的内容。
我挺悲观的,你不要指望在webview这块做太多优化(成本太大)。
少年,接受它吧。
难道不应该只生成一个UIWebView 然后 load的url变换么。 一次性搞几十个UIWebView一次性加载到view上。 如果真有这样的设计 不应该是先反思自己的么。
呵呵 过来回复是废话。
呵呵 你加一堆空白view 和加一堆有动画的view 资源占用一样? 还是只加一个view 然后 把里面的动画资源替换需要时候替换不同的资源 不用的释放掉要好一些?
我的讨论不是说怎么把webview的30m给降低。 而是说怎么合理的使用webview 而不使得app crash掉。 就算webview本身有问题。
就用了半小时 看了一下lz发的url和在so上看了看 相关内容。
然后写代码测试了一下 自己觉得比较极端的情况了。
代码没有经过严格测试,肯定有很多不合理的地方。
我只是想说明 同一个webview 不停load的话 内存不会出现巨大增加
这个是在模拟器里面 内存波动在60m 到80m之间 一共加载了40多次。
这个是在真机iPhone5上 内存波动在40m到50m之间。 也一共加载了40多次。
后面就没有跑了。
我的观点是webview固然有问题。 但是 如果是运用合理的话。 应该不会造成因为内存不断增加而导致app crash这样样子的问题出现。
而且我认为当持有webview的vc被销毁的时候。 我以为webview也会被销毁。 这样持有几十m的内存就得以回收。 这样也不会造成内存不足。 这个观点没有测试
以上, 也许有更加合理的解决方法。 我只是站在一个hello world级别上来想办法解决这个问题。
参考这篇文章和示例应给能够解决这个问题
http://blog.techno-barje.fr//post/2010/10/04/UIWebView-secrets-part1-memory-leaks-on-xmlhttprequest/
可以在 webViewDidFinishLoad 方法中设置如下:
[[NSUserDefaults standardUserDefaults] setInteger:0 forKey:@"WebKitCacheModelPreferenceKey"];
[[NSUserDefaults standardUserDefaults] setBool:NO forKey:@"WebKitDiskImageCacheEnabled"];//自己添加的,原文没有提到。
[[NSUserDefaults standardUserDefaults] setBool:NO forKey:@"WebKitOfflineWebApplicationCacheEnabled"];//自己添加的,原文没有提到。
[[NSUserDefaults standardUserDefaults] synchronize];
关于NSUserDefaults的另类用法还有比如设置UserAgent也可以通过NSUserDefaults来设置。