文档章节

Android单个应用的内存限制

linin630
 linin630
发布于 2015/01/28 11:27
字数 1334
阅读 130
收藏 1

问题:android中单个应用能申请到的最大内存是多少?

答案是:不确定。不同的手机可能会不同,主要是因为大部分手机都不是原生系统,手机厂商会根据自己的需求更改单个应用的内存限制。

就以我跟同事的手机为例:(单位:MB)

酷派大神f1:256

LG P970:48

三星9250::96

联想S720:64

小米1:64

可以看到酷派简直丧心病狂的改成256M,妈妈再也不用怕我的手机会OOM了~~

当然,这些只是系统的配置,真实的运行情况不一定符合,下面我们就来验证一下这个数字的真实性~~

先写个demo测试了一遍。大致代码如下:

public class MainActivity extends Activity implements Runnable {
	
	List<Bitmap> bs = new ArrayList<Bitmap>();
	TextView tv = null;
	String result = "";
	Handler handler = new Handler(){
		public void handleMessage(android.os.Message msg) {
			tv.setText(result);
		}
	};

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		tv = new TextView(this);
		setContentView(tv);
		long max = Runtime.getRuntime().maxMemory()/1024/1024;
		result += "测试本机型单个应用所能申请到的最大内存:"+max+"M\n";
		tv.setText(result);
		new Thread(this).start();
	}

	@Override
	public void run() {
		int i = 0;
		Runtime rt = Runtime.getRuntime();
		while (i<100) {
			i++;
			long m1 = rt.totalMemory()-rt.freeMemory();
			Bitmap b = BitmapFactory.decodeResource(getResources(), R.drawable.first_z);
			bs.add(b);
			long m2 = rt.totalMemory()-rt.freeMemory();
			if (rt.maxMemory()-rt.totalMemory()<=m2-m1) {
				//当应用已申请的最大内存跟系统限制的最大内存相差 小于 加载一张1M图片所需要的内存,不继续加载了
				result += "一张1M的图片需要内存:"+(m2-m1)/1024/1024+"M\n";
				break;
			}
		}
		result += "加载1M的图片"+i+"张后内存已不足,再加载即发生OOM!";
		handler.sendEmptyMessage(0);
	}

}

(R.drawable.first_z是一张刚好1M的图片)

不看代码也没事,我解释一下这个Activity做了什么事:在启动Activity后,开启了一个线程来加载100张1M的图片,并以强引用的形式存入List<Bitmap>中,每加载一次图片就做个判断,如果当前应用所能申请到的内存已不够加载一张1M的图片了,则不再加载。

运行的结果如下,数字表示该手机最多能加载1M的图片多少张:

酷派大神f1:34

LG P970:13

三星9250::11

联想S720:12

看到这个数字大家可能就疑惑了,LG的内存限制明明才48M,为什么却比三星、联想加载的图片多?这是因为LG加载一张1M的图片仅需要4M内存,而酷派、三星加载一张1M的图片需要7M的内存。

那么联想加载1M的图片需要多少内存呢?答案也是4M;那么就奇怪了,为什么同样是4M内存,加载的图片却比LG少呢?

我也是觉得奇怪,于是查看了下log信息,如下:

01-28 09:22:41.949: I/dalvikvm-heap(12228): Grow heap (frag case) to 11.208MB for 2073616-byte allocation
///从这里开始加载图片,多余的log我去掉了
01-28 09:22:42.005: I/dalvikvm-heap(12228): Grow heap (frag case) to 15.210MB for 4196368-byte allocation
01-28 09:22:42.224: I/dalvikvm-heap(12228): Grow heap (frag case) to 19.249MB for 4196368-byte allocation
01-28 09:22:42.509: I/dalvikvm-heap(12228): Grow heap (frag case) to 23.271MB for 4196368-byte allocation
01-28 09:22:42.699: I/dalvikvm-heap(12228): Grow heap (frag case) to 27.273MB for 4196368-byte allocation
01-28 09:22:42.862: I/dalvikvm-heap(12228): Grow heap (frag case) to 31.275MB for 4196368-byte allocation
01-28 09:22:43.011: I/dalvikvm-heap(12228): Grow heap (frag case) to 35.277MB for 4196368-byte allocation
01-28 09:22:43.170: I/dalvikvm-heap(12228): Grow heap (frag case) to 39.280MB for 4196368-byte allocation
01-28 09:22:43.317: I/dalvikvm-heap(12228): Grow heap (frag case) to 43.282MB for 4196368-byte allocation
01-28 09:22:43.467: I/dalvikvm-heap(12228): Grow heap (frag case) to 47.284MB for 4196368-byte allocation
01-28 09:22:43.625: I/dalvikvm-heap(12228): Grow heap (frag case) to 51.286MB for 4196368-byte allocation
01-28 09:22:43.790: I/dalvikvm-heap(12228): Grow heap (frag case) to 55.288MB for 4196368-byte allocation
01-28 09:22:43.940: I/dalvikvm-heap(12228): Grow heap (frag case) to 59.291MB for 4196368-byte allocation

可以发现,在加载图片之前就已经用掉了11.208M,虽然不知道联想做了什么厉害的事情,不过在加载图片前就用掉11M简直丧心病狂!

不过这样一来联想加载的图片比较少也可以理解了;因为我都是转换成MB单位的,所以可能有些误差,联想加载一张1M的图片的内存应该是要比LG多一点的。

因为联想的这种特殊情况,所以我觉得其他手机应该也肯定也会在加载图片前耗掉一些内存,于是也拿来测一下:

酷派大神:4

LG:1.6

三星:13

联想:11

可以看到,三星更加丧病~~而LG倒是只用了1.6M。

验证:根据测试所得的数据,算出加载1M图片所消耗的内存,进行验证

酷派大神f1:(256-4)/34=7.4

LG P970:(48-1.6)/13=3.6

三星9250::(96-13)/11=7.5

联想S720:(64-11)/12=4.4

从上述结果可以看出,1M图片消耗的内存与代码得到的基本符合(酷派、三星7M;LG、联想4M)。

结论:好的,让我回到本次测试的目的;我们是为了验证不同手机单个应用最大内存限制的真实性而做的测试,而从结果来看,结论是成立的!不管手机厂商把内存限制改的多么浮夸,但其真实性是不可否认的~

© 著作权归作者所有

linin630

linin630

粉丝 4
博文 34
码字总数 22734
作品 0
珠海
程序员
私信 提问
Android加载Bitmap出现OutofMemoryError的原因(官方译文)

加载Bitmap出现OutofMemoryError的原因: 1、移动设备通常有限制的系统资源。 Android设备有少的16MB内存可用于单个应用程序,虚拟机的兼容性提供了所需的最小内存为各种屏幕尺寸和密度的应用...

jdroid
2014/03/20
99
0
【Google官方教程】前言:高效的Bitmap显示

转载声明:Ryan的博客文章欢迎您的转载,但在转载的同时,请注明文章的来源出处,不胜感激! :-) http://my.oschina.net/ryanhoo/blog/88153 译者:Ryan Hoo 来源:https://developer.andro...

RyanHoo
2012/11/09
3.8K
11
配置方法数超过 64K 的应用(转)

参考自:https://developer.android.google.cn/studio/build/multidex.html 我们在开发Androi应用的时候,有时会出现以下这种错 或 这些错误都会显示一个数字:65536。这个数子很重要,他代表...

no白菜
2019/07/08
0
0
Android性能测试(内存、cpu、fps、流量、GPU、电量)——adb篇

adb 常用命令 获取连接设备号:adb devices 列出设备所有已安装的包名 (不需root权限) adb shell “pm list packages”,可以加上grep 进行筛选(windows系统使用findstr /i "xxxx" 或者 fi...

某杰
2018/05/14
0
0
Android和iOS的区别(从开发角度比较)

一、两者运行机制不同 1. iOS采用的是沙盒运行机制 (1)沙盒机制 出于安全考虑,iPhone对于安装在上面的应用程序有所限制,这个限制就是应用程序只能在为该改程序创建的文件系统中读取文件,...

安然若知
2018/06/28
0
0

没有更多内容

加载失败,请刷新页面

加载更多

OSChina 周四乱弹 —— 水果你们都没吃全

Osc乱弹歌单(2020)请戳(这里) 【今日歌曲】 @ 莱布妮子:分享五月天的单曲《温柔》@小小编辑 @cIouddyy @clouddyy 《温柔》- 五月天 手机党少年们想听歌,请使劲儿戳(这里) @FalconChe...

小小编辑
32分钟前
91
1
聚合支付网站被黑客攻击 导致数据库被篡改的防御办法

2020春节即将来临,收到新聚合支付平台网站客户的求助电话给我们Sinesafe,反映支付订单状态被修改由原先未支付修改为已支付,导致商户那边直接发货给此订单会员了,商户和平台的损失较大,很多码...

网站安全
昨天
63
0
MySQL-基于SELECT查询的UPDATE查询

我需要检查(从同一张表)基于日期时间的两个事件之间是否存在关联。 一组数据将包含某些事件的结束日期时间,另一组数据将包含其他事件的开始日期时间。 如果第一个事件在第二个事件之前完成...

javail
昨天
70
0
将PostgreSQL数据库复制到另一台服务器

我正在将生产PostgreSQL数据库复制到开发服务器。 什么是最快,最简单的方法? #1楼 pg_dump the_db_name > the_backup.sql 然后将备份复制到您的开发服务器,并使用以下命令进行还原: ps...

技术盛宴
昨天
130
0
[译]软件架构师之路

今天给大家带来一篇自己翻译的干货《软件架构师之路》。本周Github上升很快的项目。其内容对致力于成为软件架构师(不论前后端)的同学应该都会有极大的帮助。 项目地址: 中文地址 https://...

gamedilong
昨天
79
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部