017_01setImageBitmap引起的OOM分析

  OOM的全称是out of memory exception.当使用setImageBitmap()显示图片时有时会引起该异常。那么是什么原因呢?我们知道一张图片是有很多个像素点组成的,bmp格式图片一个像素需要3字节(RGB,每个颜色一个字节表示)或者4字节(RGBA)表示。如果一张图片分辨率为4266*2900 ,那么它有 12371400 像素点,使用setImageBitmap()所需内存为:12371400 *4byte=49485616字节约48M,当前模拟器设置的VM heap是32M,所以会报OOM异常。

  该如何解决呢?假设模拟器的分辨率我320*480。在分辨率有限的情况下,可以采取缩放图片的方法。4266/320 =13 2900/480 =6 选取较大的那个缩放比例来设置。

源代码如下:

 1 package com.example.day17_01pictureloader;
 2
 3  import android.app.Activity;
 4 import android.graphics.Bitmap;
 5 import android.graphics.BitmapFactory;
 6 import android.graphics.BitmapFactory.Options;
 7 import android.os.Bundle;
 8 import android.os.Debug;
 9 import android.os.Environment;
10 import android.view.Display;
11 import android.view.Menu;
12 import android.view.MenuItem;
13 import android.view.View;
14 import android.widget.ImageView;
15
16 public class MainActivity extends Activity {
17
18     @Override
19     protected void onCreate(Bundle savedInstanceState) {
20         super.onCreate(savedInstanceState);
21         setContentView(R.layout.activity_main);
22     }
23
24     public void loadpicture(View v){
25         ImageView  iv_iamge = (ImageView) findViewById(R.id.iv_image);
26         //iv_iamge.setImageResource(R.drawable.fun1);
27         String path = Environment.getExternalStorageDirectory().getAbsolutePath()
28                 +"/DCIM/100ANDRO/cameras/dd.jpg";
29         Bitmap bm = BitmapFactory.decodeFile(path);
30         iv_iamge.setImageBitmap(bm);
31     }
32
33     public void scaleloadpicture(View v){
34         String path = Environment.getExternalStorageDirectory().getAbsolutePath()
35                 +"/DCIM/100ANDRO/cameras/pp.jpeg";
36         //decode需要添加一些option
37         Options opt =new Options();
38         opt.inJustDecodeBounds = true;
39         Bitmap bm = BitmapFactory.decodeFile(path,opt);
40         int original_width = opt.outWidth;
41         int original_heigth= opt.outHeight  ;
42         System.out.println("图片的原始宽高"+original_width+","+original_heigth);
43
44         //获取屏幕的宽高
45         Display display = getWindowManager().getDefaultDisplay();
46         int screenWidth = display.getWidth();
47         int screenHeight = display.getHeight();
48         System.out.println("屏幕的宽和高: " + screenWidth + " * " + screenHeight);
49
50         //计算缩放比例
51         int scale_width =  original_width/screenWidth ;
52         int scale_height =  original_heigth/screenHeight ;
53         int scale = scale_width>scale_height? scale_width:scale_height;
54         System.out.println("缩放的比例: " + scale  );
55
56         //重新设置decode的参数,加上缩放比例的参数
57         opt.inJustDecodeBounds = false;
58        // opt.inScaled = scale;
59         opt.inSampleSize =scale;
60         bm = BitmapFactory.decodeFile(path,opt);
61
62         //将缩放后的图片加载到imageview上
63         ImageView  iv_iamge = (ImageView) findViewById(R.id.iv_image);
64         iv_iamge.setImageBitmap(bm);
65     }
66 }
 1 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 2     xmlns:tools="http://schemas.android.com/tools"
 3     android:layout_width="match_parent"
 4     android:layout_height="match_parent"
 5     android:paddingBottom="@dimen/activity_vertical_margin"
 6     android:paddingLeft="@dimen/activity_horizontal_margin"
 7     android:paddingRight="@dimen/activity_horizontal_margin"
 8     android:paddingTop="@dimen/activity_vertical_margin"
 9     tools:context="com.example.day17_01pictureloader.MainActivity"
10     android:orientation="vertical">
11
12     <TextView
13         android:layout_width="wrap_content"
14         android:layout_height="wrap_content"
15         android:text="@string/hello_world" />
16         <Button
17         android:layout_width="wrap_content"
18         android:layout_height="wrap_content"
19         android:text="加载图片"
20         android:onClick="loadpicture"/>
21            <Button
22         android:layout_width="wrap_content"
23         android:layout_height="wrap_content"
24         android:text="缩放加载图片"
25         android:onClick="scaleloadpicture"/>
26     <ImageView
27         android:id="@+id/iv_image"
28         android:layout_width="wrap_content"
29         android:layout_height="wrap_content"
30          />
31 </LinearLayout>

时间: 2024-10-02 21:06:29

017_01setImageBitmap引起的OOM分析的相关文章

记录一次OOM分析过程

工具: jstat jmap jhat 1.jstat查看gc情况 S0C.S1C.S0U.S1U:Survivor 0/1区容量(Capacity)和使用量(Used) EC.EU:Eden区容量和使用量 OC.OU:年老代容量和使用量 PC.PU:永久代容量和使用量 YGC.YGT:年轻代GC次数和GC耗时 FGC.FGCT:Full GC次数和Full GC耗时 GCT:GC总耗时 这次遇到的情况是,old区到了指定的回收阀值触发fgc,但old区回收不了,持续增长(但一直频繁fgc).

Android Memory Leak &amp; OOM 分析

1.Android 进程管理&内存 Android主要应用在嵌入式设备当中,而嵌入式设备由于一些众所周知的条件限制,通常都不会有很高的配置,特别是内存是比较有限的.如果我们编写的代 码当中有太多的对内存使用不当的地方,难免会使得我们的设备运行缓慢,甚至是死机.为了能够使得Android应用程序安全且快速的运行,Android 的每个应用程序都会使用一个专有的Dalvik虚拟机实例来运行,它是由Zygote服务进程演变过来的,也就是说每个应用程序都是在属于自己的进程中运行的.一方面,如果程序在运行

Android 内存管理 &amp;Memory Leak &amp; OOM 分析

1.Android 进程管理&内存 Android主要应用在嵌入式设备当中,而嵌入式设备由于一些众所周知的条件限制,通常都不会有很高的配置,特别是内存是比较有限的.如果我们编写的代 码当中有太多的对内存使用不当的地方,难免会使得我们的设备运行缓慢,甚至是死机.为了能够使得Android应用程序安全且快速的运行,Android 的每个应用程序都会使用一个专有的Dalvik虚拟机实例来运行,它是由Zygote服务进程演变过来的,也就是说每个应用程序都是在属于自己的进程中运行的.一方面,如果程序在运行

MAT使用及OOM分析

知识及工具推荐 1.Android资源监控工具 2.Android内存管理机制 http://blog.csdn.net/hexieshangwang/article/details/47188987 版权声明:本文为博主原创文章,未经博主允许不得转载.

java - 各类OOM分析

StackOverflowError 比较常见的问题,虚拟机栈中栈帧过多超出栈容量,常见发生在递归方法深度过深. OutOfMemoryError java heap space java堆内存不足以放下新生成的对象实例,1.考虑是否程序中存在内存泄露导致大量不需要的实例仍然占用内存未被回收2.当前内存容量是否能够足够应用运行 GC overhead limit exceeded GC回收时间过长时会抛出OutOfMemoryError,过长的定义是超过98%的时间用来做GC并且回收了不到2%的

使用Eclipse Memory Analyzer进行内存泄漏分析三部曲

源地址:http://seanhe.iteye.com/blog/898277 一.准备工作 分析较大的dump文件(根据我自己的经验2G以上的dump文件就需要使用以下介绍的方法,不然mat会出现oom)需要调整虚拟机参数 找个64位的系统在MemoryAnalyzer.ini设置-Xmx2g 如果是32位的xp可以使用下面的方法进行尝试: 安装jrockit 6.0的JDK mat使用jrockit的jdk来启动 Java代码   -vm D:/Program Files/Java/jroc

Android异常分析(转)

关于异常 异常? 异常就是一种程序中没有预料到的问题,既然是没有预料到的,就可能不在原有逻辑处理范围内,脱离了代码控制,软件可能会出现各种奇怪的现象.比如:android系统常见异常现象有应用无响应.应用停止运行.冻屏.重启.死机等,这些异常系统有统一的异常处理机制,出现异常系统就会执行相应的操作,最终有相应的现象体现出来.另外,一些不在预料之中的界面显示问题,操作问题,运行卡顿问题等也可以归于异常,只不过这种异常是人为逻辑缺陷,对系统来说是正常的,但这些缺陷在异常现象中占比却相当大,直接体现出

OOM的简单了解

1)什么是OOM? OOM,全称"Out Of Memory",翻译成中文就是"内存用完了",来源于java.lang.OutOfMemoryError.看下关于的官方说明: Thrown when the Java Virtual Machine cannot allocate an object because it is out of memory, and no more memory could be made available by the garba

Android应用开发性能优化完全分析

 应用UI性能问题分析 UI可谓是一个应用的脸,所以每一款应用在开发阶段我们的交互.视觉.动画工程师都拼命的想让它变得自然大方美丽,可是现实总是不尽人意,动画和交互总会觉得开发做出来的应用用上去感觉不自然,没有达到他们心目中的自然流畅细节:这种情况之下就更别提发布给终端用户使用了,用户要是能够感觉出来,少则影响心情,多则卸载应用:所以一个应用的UI显示性能问题就不得不被开发人员重视. 2-1 应用UI卡顿原理 人类大脑与眼睛对一个画面的连贯性感知其实是有一个界限的,譬如我们看电影会觉得画面很自然