亲宝软件园·资讯

展开

Android webView加载数据时内存溢出问题及解决

代号卧底 人气:0

Android webView加载数据时内存溢出

今天使用webView加载数据时   如果数据太长就会崩溃,造成内存溢出,在网上查找了一下资料之后   终于把它解决了,谨在此记录

1.不要在XML里面写webView 可以使用一个占位布局

<FrameLayout
    android:id="@+id/layoutWebView"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:visibility="gone"/>

2.在代码中动态创建一个webView   把这个webView放到FrageLayout这个布局中

webView = new WebViewMod(getApplicationContext());
WebSettings settings = webView.getSettings();
settings.setLayoutAlgorithm(WebSettings.LayoutAlgorithm.SINGLE_COLUMN);
webView.setScrollBarStyle(View.SCROLLBARS_INSIDE_OVERLAY);
layoutWebView.addView(webView);

3.到这里基本就OK了,你可以直接在这个WebView里面加载数据了  

WebViewMod   这个是我自定义的一个webView     用系统的WebView效果是一样的

4.在当前Activity销毁的时候  记得在onDestroy方法中销毁这个WebView

@Override
protected void onDestroy() {
    webView.removeAllViews();
    webView.destroy();
    super.onDestroy();
}

大功告成!

Android内存问题 (内存溢出 内存泄漏 内存抖动)

内存溢出:指程序在申请内存时,没有足够的内存空间供其使用,出现out of memory

Android系统为每个应用程序申请到的内存有限,一般为64M或者128M等,我们可以在清单文件中进行配置,android:largeheap = "true" 从而给APP申请更大的内存空间;

内存泄漏: 指程序在申请内存后,被某个对象一直持有,无法释放已申请的内存空间

一次内存泄露危害可以忽略,但内存泄露堆积后果很严重,无论多少内存,迟早会被占光。

区别:单例模式在Android开发中会经常用到,但是如果使用不当就会导致内存泄露。因为单例的静态特性使得它的生命周期同应用的生命周期一样长,如果一个对象已经没有用处了,但是单例还持有它的引用,那么在整个应用程序的生命周期它都不能正常被回收,从而导致内存泄露

如何避免呢?全局的上下文Application Context就是应用程序的上下文,和单例的生命周期一样长,这样就避免了内存泄漏。单例模式对应应用程序的生命周期,所以我们在构造单例的时候尽量避免使用Activity的上下文,而是使用Application的上下文

静态变量导致内存泄露?静态变量存储在方法区,它的生命周期从类加载开始,到整个进程结束。

一旦静态变量初始化后,它所持有的引用只有等到进程结束才会释放。

如何解决呢?Info作为Activity的静态成员,并且持有Activity的引用,但是sInfo作为静态变量,生命周期肯定比Activity长。

所以当Activity退出后,sInfo仍然引用了Activity,Activity不能被回收,这就导致了内存泄露。

非静态内部类导致内存泄露?非静态内部类(包括匿名内部类)默认就会持有外部类的引用,当非静态内部类对象的生命周期比外部类对象的生命周期长时,就会导致内存泄露。

常见 (Handler,Thread,AsyncTask)

未取消注册或回调导致内存泄露?比如我们在Activity中注册广播,如果在Activity销毁后不取消注册,那么这个刚播会一直存在系统中,同上面所说的非静态内部类一样持有Activity引用,导致内存泄露。因此注册广播后在Activity销毁后一定要取消注册

集合中的对象未清理造成内存泄露?在循环中把引用o释放了,但是它被添加到了objectList中,所以objectList也持有对象的引用,此时该对象是无法被GC的。因此对象如果添加到集合中,还必须从中删除,最简单的方法防止集合类泄漏内存的方法

解决办法:置空集合对象即可

资源未关闭或释放导致内存泄露?在使用流或者等资源时要及时关闭。这些资源在进行读写操作时通常都使用了缓冲,如果及时不关闭,这些缓冲对象就会一直被占用而得不到释放,以致发生内存泄露。因此我们在不需要使用它们的时候就及时关闭,以便缓冲能及时得到释放,从而避免内存泄露

解决办法Webview下面的持有Activity引用,造成Webview内存无法释放,即使是调用了Webview.destory()}等方法都无法解决问题(Android5.1之后)。

最终的解决方案是:在销毁WebView之前需要先将WebView从父容器中移除,然后在销毁WebView。

内存抖动:是指在短时间内有大量的对象被创建或者被回收的现象,内存抖动出现原因主要是频繁(很重要)在循环里创建对象(导致大量对象在短时间内被创建,由于新对象是要占用内存空间的而且是很频繁

内存抖动结果:如果抖动很频繁,会导致垃圾回收机制频繁运行(短时间内产生大量对象,需要大量内存,而且还是频繁抖动,就可能会需要回收内存以用于产生对象,垃圾回收机制就自然会频繁运行了)。综上就是频繁内存抖动会导致垃圾回收频繁运行。

尽量避免在循环体内创建对象,应该把对象创建移到循环体外。

注意自定义View的onDraw()方法会被频繁调用,所以在这里面不应该频繁的创建对象。

当需要大量使用Bitmap的时候,试着把它们缓存在数组中实现复用。

对于能够复用的对象,同理可以使用对象池将它们缓存起来。

小结:JVM以Class为执行单元,Android虚拟机以Dex执行单元,编译流程JVM直接通过Javac即可加载。

Android 虚拟机需要先编译成dex,然后编译成apk。最后执行

Android  Art虚拟机在安装的时候讲dex缓存本地机器码,安装比较慢,耗存储空间

Android  Dalvik虚拟机在程序运行过程中进行翻译。节省空间,耗cpu时间。以空间换时间的典型

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持。

加载全部内容

相关教程
猜你喜欢
用户评论