Android 内存溢出管理与测试
今天发现正在做的项目,时不时的会报错:dalvikvm heap out of memory on a 7458832-byte allocation (堆分配的内存溢出)
为什么会内存溢出呢?我以前从未遇见这种情况。后来在网上查了查资料,还是挺多的。
怎么说呢?因为Android开发基本上是以java语言为基础,那么程序是在java虚拟机上运行的。而虚拟机不允许单个程序中的Bitmap占用超过8M的内存,从报错的日志可以看出:7458832-byte大约就是7M多的样子,基本吻合上述数据。在我的项目中大量的使用到了各种图片,因此是因为图片导致内存溢出的的可能性很高。
那么,下面就提供一下解决方案:
第一种方案:
Android堆内存也可自己定义大小 和 优化Dalvik虚拟机的堆内存分配(LZ没试过,不过网上很多人都说可行)。
强制定义自己软件的对内存大小,我们使用Dalvik提供的 dalvik.system.VMRuntime类来设置最小堆内存为例:
private final static int CWJ_HEAP_SIZE = 6* 1024* 1024 ;
VMRuntime.getRuntime().setMinimumHeapSize(CWJ_HEAP_SIZE); //设置最小heap内存为6MB大小。当然对于内存吃紧来说还可以通过手动干涉GC去处理
第二种方案:
手动的回收内存。
示例代码如下:bit为Bitmap对象
if (bit != null && !bit.isRecycled()) {
bit.recycle();
bit = null;
}
System.gc();
bitmap.recycle()方法用于回收该bitmap所占用的内存,用System.gc()调用一下系统的垃圾回收器。
需要注意的是:回收内存要及时,比如说SurfaceView,就应该在onSurfaceDestroyed这个方法中回收。如果Activity使用了bitmap,就可以在onStop或者onDestroy方法中回收等等。
我首先就是用的这种方法,修改后发现bug出现的频率减小了,但仍然存在。
第三种方案:
既然是图的问题,那就从图片下手。就是使图片体积大小变小。
这也分为两个方面:
1、分辨率不变,图片大小减小2、分辨率改变,图片减小。(用PS都很容易的)
需要注意的是:不要减小得太小而影响了人眼看上去的美感。
以上三种方案,后两种较简单且常用。
另外,因为是Android的图片导致的内存问题,那么就总结了一下与图片相关的方法的性能,结果很有收获啊……(不看不知道,一看吓一跳)
测试的环境为:笔记本i3处理器,64位win7系统,测试手机为小米2S,测试图片大小为500KB
比较Drawable与Bitmap占用内存大小
比较BitmapFactory类的decodeResource方法与decodeStream方法的效率
以及优化后的BitmapFactory类的decodeResource方法。
下面贴上代码与运行图:(每次请只运行一个方法,隐藏另外的三种方法)
public class MainActivity extends Activity {
int number = 1000;
Drawable[] array;
Bitmap bitmap[];
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
testDrawable();
// testBitmap_decodeResource();
// testBitmap_decodeStream();
//testnewBitmap_decodeResource();
}
/**
* 优化后的BitmapFactory类的decodeResource方法
*/
private void testnewBitmap_decodeResource() {
bitmap = new Bitmap[number];
for (int i = 0; i < number; i++) {
Log.i("", "测试第" + (i + 1) + "张图片");
//压缩,用于节省BITMAP内存空间--解决BUG的关键步骤
BitmapFactory.Options opts = new BitmapFactory.Options();
opts.inSampleSize = 2;//这个的值压缩的倍数(2的整数倍),数值越小,压缩率越小,图片越清晰
//返回原图解码之后的bitmap对象
bitmap[i] = BitmapFactory.decodeResource(getResources(),
R.drawable.begin_background, opts);
}
}
/**
* BitmapFactory类的decodeStream方法
*/
private void testBitmap_decodeStream() {
bitmap = new Bitmap[number];
for (int i = 0; i < number; i++) {
Log.i("", "测试第" + (i + 1) + "张图片");
bitmap[i] = BitmapFactory.decodeStream(getResources()
.openRawResource(R.drawable.begin_background));// 这里换了方法
}
}
/**
* BitmapFactory类的decodeResource方法
*/
private void testBitmap_decodeResource() {
bitmap = new Bitmap[number];
for (int i = 0; i < number; i++) {
Log.d("", "测试第" + (i + 1) + "张图片");
bitmap[i] = BitmapFactory.decodeResource(getResources(),
R.drawable.begin_background);
}
}
/**
* Drawable的使用
*/
private void testDrawable() {
array = new BitmapDrawable[number];
for (int i = 0; i < number; i++) {
Log.w("", "测试第" + (i + 1) + "张图片");
array[i] = getResources().getDrawable(R.drawable.begin_background);
}
}
}
首先贴出 Drawable的使用 的运行结果:(顺利测试完1000张图片)

BitmapFactory类的decodeResource方法运行结果:(居然只有11张)

运行优化后的BitmapFactory类的decodeResource方法:(优化后可达到46张,且opts.inSampleSize = n;N的参数设置得越大可达到的数量越多,但损失了图片质量)

BitmapFactory类的decodeStream方法:(可达22张图片)

这下,相信大家对Android中与图片相关的这几种方法的性能有直观的认识了吧。其实,在测试时除了看到数量外,还可以看到运行时间上的差距。
其实,综合上面产生bitmap方法,可以得出一种最优的方法:(环境以上面其他方法相同)
public void test() {
bitmap = new Bitmap[number];
for (int i = 0; i < number; i++) {
Log.i("", "测试第" + (i + 1) + "张图片");
BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = 2;
bitmap[i] = BitmapFactory.decodeStream(getResources()
.openRawResource(R.drawable.begin_background), null,
options);
}
}
最终测试得到的数据是,可以测试80多张图片。(图片也与其他方法测试的相同)
Android 内存溢出管理与测试的更多相关文章
- 【转载】Android 内存溢出如何发生的。
[转载]Android 内存溢出如何发生的. 且谈Android内存溢出 前言 关于android的内存溢出在创新文档库中也有不少,网络上也有很多这方面的资料.所以这遍文章不算是正真意义上的创新,仅仅 ...
- Android 内存溢出处理方案
转自 : http://www.cnblogs.com/hello-ruby/archive/2013/04/19/3031098.html 首先我们来看看android内存溢出的原因,有可能是: 由 ...
- android 内存溢出问题分析
最近的项目中,内存一直再增长,但是不知道是什么问题,导致内存溢出,在网上看到了这么一篇关于内存分析与管理的文章,解决了部分问题,感觉这篇文 章还不错,就转帖到我的blog上了,希望对大家有所帮助. ...
- Android内存溢出、内存泄漏常见案例及最佳实践总结
内存溢出是Android开发中一个老大难的问题,相关的知识点比较繁杂,绝大部分的开发者都零零星星知道一些,但难以全面.本篇文档会尽量从广度和深度两个方面进行整理,帮助大家梳理这方面的知识点(基于Jav ...
- Android内存溢出解决方案(OOM)
众所周知,每个Android应用程序在运行时都有一定的内存限制,限制大小一般为16MB或24MB(视平台而定).因此在开发应用时需要特别关注自身的内存使用量,而一般最耗内存量的资源,一般是图片.音频文 ...
- Android 内存溢出解决方案(OOM) 整理总结
在最近做的工程中发现加载的图片太多或图片过大时经常出现OOM问题,找网上资料也提供了很多方法,但自己感觉有点乱,特此,今天在不同型号的三款安卓手机上做了测试,因为有效果也有结果,今天小马就做个详细的总 ...
- Android 内存溢出解决方案(OOM) 整理总结<转>
在最近做的工程中发现加载的图片太多或图片过大时经常出现OOM问题,找网上资料也提供了很多方法,但自己感觉有点乱,特此,今天在不同型号的三款安卓手机上做了测试,因为有效果也有结果,今天小马就做个详细的总 ...
- Android内存进程管理机制
参考文章: http://www.apkbus.com/android-104940-1-1.htmlhttp://blog.sina.com.cn/s/blog_3e3fcadd0100yjo2.h ...
- android 内存溢出与内存泄露
内存溢出就是软件运行需要的内存,超出了java虚拟机给他分配的可用的最大内存 内存泄露就是在缓存图片文字等等的时候,没有关闭流所导致的内存泄露
随机推荐
- 洛谷 P1373 小a和uim之大逃离
2016-05-30 12:31:59 题目链接: P1373 小a和uim之大逃离 题目大意: 一个N*M的带权矩阵,以任意起点开始向右或者向下走,使得奇数步所得权值和与偶数步所得权值和关于K的余数 ...
- Java程序员的10道XML面试题
包括web开发人员的Java面试在内的各种面试中,XML面试题在各种编程工作的面试中很常见.XML是一种成熟的技术,经常作为从一个平台到其他平台传输数据的标准.XML面试问题包括用于转换XML文件的X ...
- Google Android官方文档进程与线程(Processes and Threads)翻译
android的多线程在开发中已经有使用过了,想再系统地学习一下,找到了android的官方文档,介绍进程与线程的介绍,试着翻译一下. 原文地址:http://developer.android.co ...
- [OC Foundation框架 - 21] NSSet集合 & 集合之间的转换
A.NSSet 跟NSArray一样,不可变 NSArray 自然顺序 NSSet是无序的 NSSet不允许存入重复元素,可以用来过滤重复元素 也有可变的NSMutableSet B.集合转换 ...
- [OC Foundation框架 - 8] NSArray排序
1.派生 voidarrayNew() { NSArray*array = [NSArrayarrayWithObjects:",nil]; NSArray*array2 = [arraya ...
- TabControl控件的美化
文件下载:http://files.cnblogs.com/zfanlong1314/TabControlEX.rar 本文转载:http://www.cnblogs.com/lmlblog/arch ...
- Nginx开发从入门到精通
nginx由于出色的性能,在世界范围内受到了越来越多人的关注,在淘宝内部它更是被广泛的使用,众多的开发以及运维同学都迫切的想要了解nginx模块 的开发以及它的内部原理,但是国内却没有一本关于这方面的 ...
- [安卓开发]App Widget开发入门指导
本节所要讲的主要内容包括Android桌面小部件.App Widget的开发入门指导,并通过一个简单实例的形式来直观的讲解App Widget. 一.Widget .App Widget .Web A ...
- Behavioral模式State模式
1.意向 同意一个目标,然后改变其内部状态,改变它的行为. 对象似乎改变它的类别. 2.别名 状态对象(Objects for States) 3.动机 考虑一个表示网络连接的类TCPConnecti ...
- iOS开发——数据持久化Swift篇&SettingBundle
SettingBundle import UIKit class ViewController: UIViewController { var userDefault = NSUserDefaults ...