android Menory 小结
- 不建议在Activity中使用static变量,考虑使用Application。当然,staticfinal例外
但Application也不要cache某个Activity使用的View,如果cache也一定要在这个ActivityDestroy()时手动清空Application中对view的cache。
- 线程造成内存泄露。
publicclassMyActivityextendsActivity{
@Override
publicvoidonCreate(BundlesavedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
newMyThread().start();
}
privateclassMyThreadextendsThread{
@Override
publicvoidrun(){
super.run();
//dosomthing
}
}
}
假设MyThread的run函数是一个很费时的操作,当我们开启该线程后,将设备的横屏变为了竖屏,一般情况下当屏幕转换时会重新创建Activity,按照我们的想法,老的Activity应该会被销毁才对,然而事实上并非如此。
由于我们的线程是Activity的内部类,所以MyThread中保存了Activity的一个引用,当MyThread的run函数没有结束时,MyThread是不会被销毁的,因此它所引用的老的Activity也不会被销毁,因此就出现了内存泄露的问题
3.Bitmap与Drawable
Bitmap与Drawable的比较
对比项 | Bitmap | Drawable |
显示清晰度 | 相同 | 相同 |
占用内存 | 大 | 小 |
支持缩放 | 是 | 是 |
支持色相色差调整 | 是 | 否 |
支持旋转 | 是 | 是 |
支持透明色 | 是 | 是 |
绘制速度 | 慢 | 快 |
支持像素操作 | 是 | 否 |
Drawable在内存占用和绘制速度这两个非常关键的点上胜过Bitmap(GoogleAndroid开发示例中提到绘制Bitmap的速度要快于Drawable,但经过实际测试后发现恰恰相反)。
Bitmap相对于Drawable来说又可以调整色差色相以及直接对图片的各相素进行操作。
- 位图Bitmap占用内存
比如一个320*480的图,
320*480*Config+1k(imageinfo)
android.graphics.Bitmap.Config=ARGB_8888(32bit)
ARGB_4444(16bit)
RGB_565(16bit)
/**
*以最省内存的方式读取本地资源的图片
*@paramcontext
*@paramresId
*@return
*/
publicstaticBitmapreadBitMap(Contextcontext,intresId){
BitmapFactory.Optionsopt=newBitmapFactory.Options();
//按每像素2字节读取,默认argb_8888是4字节
opt.inPreferredConfig=Bitmap.Config.RGB_565;
//读取图片时内存不足自动回收本bitmap
opt.inPurgeable=true;
//应该是共享流,以便因内存不足回收后,再次调用可以后台自动读取
opt.inInputShareable=true;
//获取资源图片
InputStreamis=context.getResources().openRawResource(resId);
returnBitmapFactory.decodeStream(is,null,opt);
}
5.
异常捕获,避免程序崩溃
try{
Bitmapbmp=BitmapFactory.decodeFile(path,options);
}catch(OutOfMemoryErrore){
//提示系统,进行内存回收
System.gc();
//清除程序缓存
clearCache();
}
- VMRuntime.getRuntime().setMinimumHeapSize(NewSize);
堆(HEAP)是VM中占用内存最多的部分,通常是动态分配的。堆的大小不是一成不变的,通常有一个分配机制来控制它的大小。比如初始的HEAP是4M大,当4M的空间被占用超过75%的时候,重新分配堆为8M大;当8M被占用超过75%,分配堆为16M大。倒过来,当16M的堆利用不足30%的时候,缩减它的大小为8M大。重新设置堆的大小,尤其是压缩,一般会涉及到内存的拷贝,所以变更堆的大小对效率有不良影响。
上面只是个例子,不过可以看到三个参数:maxheapsize,minheapsize,heaputilization(堆利用率)。
MaxHeapSize,是堆内存的上限值,Android的缺省值是16M(某些机型是24M),对于普通应用这是不能改的。函数setMinimumHeapSize其实只是改变了堆的下限值,它可以防止过于频繁的堆内存分配,当设置最小堆内存大小超过上限值时仍然采用堆的上限值,对于内存不足没什么作用。
setTargetHeapUtilization(floatnewTarget)可以设定内存利用率的百分比,当实际的利用率偏离这个百分比的时候,虚拟机会在GC的时候调整堆内存大小,让实际占用率向个百分比靠拢。
rivatefinalstaticfloatTARGET_HEAP_UTILIZATION=0.75f;在程序onCreate时就可以调用VMRuntime.getRuntime().setTargetHeapUtilization(TARGET_HEAP_UTILIZATION);即可。
6.内部类的对象作用域超出Activity的范围:比如定义了一个内部类来存储数据,又把这个内部类的对象传给了其它Activity或者Service等。因为内部类的对象会持有当前类的引用,所以也就持有了Context的引用。解决方法是把内部类抽取出来变成一个单独的类,或者把避免内部对象作用域超出Activity的作用域
更多相关文章
- Android(安卓)Weekly Notes Issue #223
- Android(安卓)studio 如何设置字体大小
- android下载文件下载不完全解决方案
- Android(安卓)内存信息查看
- Android画布(cavas)
- Android(安卓)软引用内存缓存图片
- Android之获取画面大小
- android系统信息(内存,cpu,sd卡,电量,版本)的获取
- Android(安卓)字体大小怎么自适应不同分辨率?