面试

Application与内存泄漏

2017-02-15  本文已影响409人  岛在深海处

1.Application

强调一个Dalvik虚拟机因为一个App有可能有多个Dalvik虚拟机就有多个不同的Application实例(Application的onCreate()方法也会执行多次Android中Application的onCreate多次调用问题),也就是传说中的多进程模式。多进程模式通过AIDL进行通信。

由于在Context中可以通过getApplicationContext()获取到Application对象,或者是通过Activity.getApplication()、Service.getApplication()获取到Application(都是同一个对象),所以可以在Application保存全局的数据,供所有的Activity或者是Service使用。但是这里存在着一个坑,那就是在低内存情况下,Application有可能被销毁,从而导致保存在Application里面的数据信息丢失,最后程序错乱,甚至是Crash。所以当你想在Application保存数据的时候,请做好为空判断,或者是选择其他方式保存你的数据信息。不要在Android的Application对象中缓存数据!

最后,就是要注意Application的生命周期,他和Dalvik虚拟机生命周期一样长,所以在进行单例或者是静态变量的初始化操作时,一定要用Application作为Context进行初始化,否则会造成内存泄露的发生(若用Activity的实例,会造成该 Activity 在被销毁时将无法被回收)。使用Dialog的时候一般使用Activity作为Context,但是也可以使用Application作为上下文,前提是你必须设置Window类型为TYPE_SYSTEM_DIALOG,并且申请相关权限。这个时候弹出的Dialog是属于整个Application的,弹出这个Dialog的Activity销毁时也不会回收Dialog,只有在Application销毁时,这个Dialog才会自动消失。

参考:谈谈你对Application类的理解

2.内存泄漏

内存泄漏:是指程序由于错误或漏洞造成的内存占用过多,或占用内存后无法释放
内存溢出:是指已有的数据超过了其获得到的内存所能存储的范围,比如用一个字节存放1000这个数字就属于内存溢出

(1)Activity中内存泄漏的情况

一般是因为Activity的引用不能及时释放造成Activity销毁时不能被GC回收。

解决办法:使用静态内部类不会持有一个外部 Activity 的隐式引用,而且该 Activity 也会在配置改变后被回收,如果是线程的话则在onDestroy()方法中关闭线程。如果是AsycTask的话可以用静态内部类,由于静态内部类不持有Activity的引用所以可以将Activity实例弱引用(可见参考2)。

解决办法:最简单的方法是在onDestory方法中将静态变量activity置空,这样垃圾回收器就可以将静态变量回收。

解决办法:最简单的方法是在onDestory方法中将静态变量View置空,这样垃圾回收器就可以将静态变量回收。

解决办法:context=context.getApplicationContext();

解决办法:创建一个静态Handler内部类,然后对Handler持有的对象使用弱引用,这样在回收时也可以回收Handler持有的对象,这样虽然避免了Activity泄漏,不过Looper线程的消息队列中还是可能会有待处理的消息,所以我们在Activity的Destroy时或者Stop时应该移除消息队列中的消息

总结:详见参考2

参考:
1.在Activity中使用Thread导致的内存泄漏
2.Android性能优化之常见的内存泄漏

上一篇 下一篇

猜你喜欢

热点阅读