本帖最后由 小鲁哥哥 于 2017-1-20 11:14 编辑
【济南中心】Android就业面试技巧系列-技术篇(内存优化)内存泄漏原因: 内存泄漏就是我们对某一内存空间的使用完成后没有释放。
主要原因:导致内存泄漏最主要的原因就是某些长存对象持有了一些其它应该被回收的对象的引用,导致垃圾回收器无法去回收掉这些对象。
出现的场景:
1.数据库的cursor没有关闭;
2.构造adapter时,没有使用缓存contentview;
3.Bitmap对象不使用时采用recycle()释放内存;
4.activity中的对象的生命周期大于activity; 优化内存的方法: 1.减少不必要的全局变量尽量避免static成员变量引用资源耗费过多的实例,比如Context。
因为Context的引用超过它本身的生命周期,会导致Context泄漏。所以尽量使用Application这种Context类型。
你可以通过调用Context.getApplicationContext()或 Activity.getApplication()轻松得到Application对象。
2.Cursor(游标)回收
Cursor是Android查询数据后得到的一个管理数据集合的类,在使用结束以后。应该保证Cursor占用的内存被及时的释放掉,而不是等待GC来处理。并且Android明显是倾向于编程者手动的将Cursor close掉,因为在源代码中我们发现,如果等到垃圾回收器来回收时,会给用户以错误提示。 3.Receiver(接收器)回收 调用registerReceiver()后未调用unregisterReceiver(). 当我们Activity中使用了registerReceiver()方法注册了BroadcastReceiver,一定要在Activity的生命周期内调用unregisterReceiver()方法取消注册
也就是说registerReceiver()和unregisterReceiver()方法一定要成对出现,通常我们可以重写Activity的onDestory()方法,在onDestory里进行unregisterReceiver操作 4.Stream/File(流/文件)回收 主要针对各种流,文件资源等等如: InputStream/OutputStream,SQLiteOpenHelper,SQLiteDatabase,Cursor,文件,I/O,Bitmap图片等操作等都应该记得显示关闭。 5.避免创建不必要的对象 最常见的例子就是当你要频繁操作一个字符串时,使用StringBuffer代替String。 还比如:使用int数组而不是Integer数组。 避免创建短命的临时对象,减少对象的创建就能减少垃圾收集,进而减少对用户体验的影响。 6.避免内部Getters/Setters 在Android中,虚方法调用的代价比直接字段访问高昂许多。通常根据面向对象语言的实践,在公共接口中使用Getters和Setters是有道理的,但在一个字段经常被访问的类中宜采用直接访问。
因为内存溢出所引发的OOM异常,我们如何避免OOM。举一个例子: [Java] 纯文本查看 复制代码 new Thread(new Runnable() {
@Override
public void run() {
SystemClock.sleep(10000);
}
}).start(); 在Activity里声明了一个匿名内部类,如果Activity在销毁之前,线程的任务还未完成, 那么将导致Activity的内存资源无法回收,造成内存泄漏。 解决办法就是使用静态内部类,并且及时关闭线程,如下: [Java] 纯文本查看 复制代码 private static class MyThread extends Thread {
private boolean mRunning = false;
@Override
public void run() {
mRunning = true;
while (mRunning) {
SystemClock.sleep(1000);
}
}
public void close() {
mRunning = false;
}
} 我们在Activity退出时,可以在onDestroy()方法中显示的调用mThread.close();以此来结束该线程,这样在避免Activity OOM的同时也避免了线程的内存泄漏问题。
|