Android加载图片占用内存

本文探讨了Android中图片加载占用内存的问题,指出大尺寸图片可能导致内存溢出。介绍了Bitmap在内存中的存储方式,以及如何通过Runtime获取JVM内存信息。文章详细解释了Android系统如何根据屏幕像素密度缩放图片,导致内存占用不同。为了优化内存,建议使用BitmapFactory.Options进行采样率设置以降低图片分辨率,并调整像素格式减少每个像素的字节数。通过这些方法,可以显著降低图片内存占用,避免OOM异常,提升应用性能。
摘要由CSDN通过智能技术生成

图片在内存中的存储基于位图模式(通常也称作Bitmap),它把图片的长宽定义成多个像素点,每个像素点的颜色值有几个像素来保存,对那些尺寸比较大的图片一张可能就占据十兆左右的空间,应用只要多存储一些大尺寸照片就会导致内存溢出。Android的应用运行在JVM虚拟机上,每个JVM虚拟机进程分配的内存有限,这样才能保证多个应用同时运行时每个程序都有机会执行。系统究竟为每个应用分配的内存值大小是多少,Java提供了Runtime运行时类它可以提供JVM的内存信息。

Log.e(TAG, "Total Memory = " + Runtime.getRuntime().totalMemory());
Log.e(TAG, "Free Memory = " + Runtime.getRuntime().freeMemory());
Log.e(TAG, "Max Memory = " + Runtime.getRuntime().maxMemory());
Total Memory = 2754792
Free Memory = 1267952
Max Memory = 268435456

Runtime三个方法提供的数据都是JVM进程的内存数,其中totalMemory代表当前JVM从操作系统已经申请到的内存大小,freeMemory的值等于totalMemory减去已经使用了的内存大小,maxMemory代表JVM进程可以向操作系统申请的最大内存值。 从测试代码看当前申请totalMemory到的内存才2M多,而最大申请内存有268M那么大,如果应用继续执行需要更多的内存,totalMemory会不断地增大,最大增长到maxMemory的大小,之后继续申请内存就会导致内存溢出,JVM抛出OutOfMemory异常。

public void testMemory(View view) {
     byte[][] array = new byte[1024 * 1024][];
      for (int i = 0; i < 1024; i++) {
         array[i] = new byte[1024 * 1024 * 4];
     }
}

上面的内存申请代码首先定义了一个1024 * 1024长度的二维数组,之后为每个元素申请4 * 1024 * 1024也就是4M的内存空间,由于申请的内存始终都被array数组引用无法被回收,最终JVM抛出了OOM异常。从异常消息中可以看出系统限制了分配最大内存268M和前面获取值是一致的。

java.lang.OutOfMemoryError: Failed to allocate a 4194320 byte allocation with 2395752 free bytes and 
2MB until OOM, max allowed footprint 268435456, growth limit 268435456

那么有没有方法增加最大分配内存大小呢,在AndroidManifest.xml文件的application节点有个属性android:largeHeap,配置属性值为true系统就会为应用提供更大的内存空间。

Total Memory = 2732016
Free Memory = 1202328
Max Memory = 536870912
java.lang.OutOfMemoryError: Failed to allocate a 4194320 byte allocation with 2133584 free bytes and 
2MB until OOM, max allowed footprint 536870912, growth limit 536870912

重新运行前面的测试代码就会发现最大内存值变成了536M,比以前足足大了一倍,但largeHeap选项不建议一般的应用开启,试想如果所有应用都申请内存变大最终还是会导致内存不足的情况。

图片占用内存

应用中使用到的图片通常会放置在资源文件夹res/drawable-xxx、assets文件夹、本地缓存目录、用户相册,还有一些图片需要从网络上加载。首先来看从res资源文件夹加载图片实现,drawable文件夹通常看到的有drawable、drawable-hdpi、drawable-xxhdpi等多个文件夹,应用在不同尺寸的屏幕下会使用不同像素密度文件下的图片。如果同一副图片放在不同的像素密度资源文件夹下,将它加载到内存中它的大小是不是完全一样的呢?


                
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值