题目:请简单说一下你在android开发过程中如何对内存进行优化。
分析:众所周知,Android应用程序是运行在java虚拟机之中,垃圾回收采用的是java当中的GC机制,由系统进行整体调度,开发者无法直接干预,因此在开发过程中对内存的合理使用就显得尤其重要。
1.对Bitmap的优化:
在Android应用中,最消耗内存的就是Bitmap的图片资源。而在android系统中,读取Bitmap时,分配给虚拟机中堆栈的大小只有8M,如果超出了,就会OOM(Out Of Memory)。
a>要及时回收Bitmap,当Bitmap使用完毕后,执行如下代码:
if(bitmap && !bitmap.isRecycle()){ bitmap.recycle(); bitmap = null; } system.gc();注意,最后一句system.gc();只是请求系统尽快进行垃圾回收,而不能保证系统立即做出反应。
由于生成Bitmap对象是通过调用JNI接口实现的,释放同样也需要调用JNI接口。所以加载Bitmap对象到内存之后是包含两部分区域的,一个是java的部分,一个是C的部分。系统的GC机制在回收的时候只能回收java部分的内存,而不能释放C部分的内存,C部分的内存只能通过调用recycle()接口来释放。
那若不调用recycle()接口,是否就一定存在内存泄漏呢?也不是。当应用的进程被应用自己或者被系统杀死后,整个进程的内存就会被释放,当然也包含C的部分。
b>捕获异常
Bitmap bitmap = null; try{ bitmap = BitmapFactory.decodeFile(path); }catch(OutOfMemoryError e) { // do something } if(!bitmap) return default_bitmap;这样,在发生OOM的时候,应用就不会崩溃,而是会显示一张默认的图片。注意在catch的地方catch的是Error,而不是Exception。
c>缓存通用的Bitmap对象
对于那种在应用中要多次重复用到的图片,可以在内存中只保留一个副本,即可以定义成全局变量或者静态变量。
d>压缩图片
2.使用软引用和弱引用
Java将对象的引用分为四种级别,从而使程序能够更灵活的控制对象的生命周期。四种级别从高到低分别是:强引用,软引用,弱引用,虚引用。
a>强引用就是通常的用法,不再赘述。
b>软引用,如果一个对象只有软引用,那么当内存足够的时候,它和强引用的对象没区别;当内存不足时,系统会将它回收掉。
private Map<String , SoftReference<Bitmap>> imageCache = new HashMap<String, SoftReference<Bitmap>>; public void addBmToCache(String path){ Bitmap bm = BitmapFactory.decodeFile(path); SoftReference<Bitmap> softbm = new SoftReference<Bitmap>(bm); imageCache.put(path, softbm); } public Bitmap getBmByPath(String path){ SoftReference<Bitmap> softbm = imageCache.get(path); if(softbm == null) return null; Bitmap bm = softbn.get(); return bm; }
c>弱引用,如果一个对象只有弱引用,那么在GC线程扫描过程中,一旦发现此类对象,无论内存是否足够,这个对象都将被回收。
软引用和弱引用的区别在于,弱引用的生命周期更短,随时有可能被回收;软引用只有在内存不足的时候才会被回收。
d>虚引用,形同虚设,主要是用来跟踪内存回收情况,必须和引用队列联合进行使用。
3.自己实现bitmap缓存管理机制:
最近的google大会上发布消息,说Android系统的源码中将更加频繁的对软引用进行回收,这就会导致原来java提供的软引用机制效果降低,所以我们在做内存优化的时候可能就需要自行实现一个缓存的管理机制,可以用LRU,LFU或者FIFO等策略来实现。
由于笔者水平有限,给各面试题提供的思路或代码难免会有错误,还请读者批评指正。另外,热忱欢迎读者能够提供更多、更好的面试题,本人将感激不尽。如有任何意见或建议,欢迎在评论中告知。
博主徐方磊对本博客文章享有版权。网络转载请注明出处http://blog.csdn.net/shishengshi。整理出版物请和作者联系。