Image too large in Android causes memory overflow, OOM (OutOfMemory) Exception workaround

Source: Internet
Author: User

When we are in the process of doing the project, when we encounter the picture, we should consider the size of the image, the size of the memory, the reason is that Android allocated to the size of the bitmap only 8M, imagine that we use a mobile phone to take pictures, ordinary a picture does not have to 1 m above, So Android processing pictures have to consider the picture too large caused by memory anomalies.

At that time simply cached the image to the local and then compress the picture, but feel that the problem is not a good solution, but to reduce the probability of occurrence

Here, I will re-organize the methods of the predecessors to facilitate their use later.

1. Do some processing on memory references, often soft references, hardened references, weak references

Import Java.lang.ref.phantomreference;import Java.lang.ref.reference;import Java.lang.ref.referencequeue;import    Java.lang.reflect.field;public class Test {public static Boolean isrun = true;        public static void Main (string[] args) throws Exception {String abc = new String ("abc");                                                                                                                                                                                         System.out.println (Abc.getclass () + "@" + abc.hashcode ()); Final Referencequeue R        Eferencequeue = new referencequeue<string> (); New Thread () {public void run () {while (Isrun) {Object o = referencequeue.                    Poll (); If(o! = null)                                    {try {Field rereferent = Reference.class                            . Getdeclaredfield ("referent");                            Rereferent.setaccessible (TRUE);                            Object result = Rereferent.get (o);                                    SYSTEM.OUT.PRINTLN ("GC would collect:" + result.getclass () + "@"                        + Result.hashcode ());                        } catch (Exception e) {e.printstacktrace ();        }}}}}.start ();        phantomreference<string> abcweakref = new phantomreference<string> (ABC, referencequeue);        ABC = NULL;        Thread.CurrentThread (). Sleep (3000);        System.GC ();        Thread.CurrentThread (). Sleep (3000);    Isrun = false; }}

Results:

class [email protected]
GC would collect:class [email protected]

2. Work directly in memory when loading pictures in memory
A. Boundary compression

@SuppressWarnings ("unused") Private Bitmap Copressimage (String imgpath) {file picture = new File (Imgpath);    Options bitmapfactoryoptions = new Bitmapfactory.options ();    The following setting is to change the picture boundary to an adjustable bitmapfactoryoptions.injustdecodebounds = true;    Bitmapfactoryoptions.insamplesize = 2;    int outwidth = Bitmapfactoryoptions.outwidth;    int outheight = Bitmapfactoryoptions.outheight;    Bmap = Bitmapfactory.decodefile (Picture.getabsolutepath (), bitmapfactoryoptions);    float Imagew = 150;    float Imageh = 150;    int yratio = (int) math.ceil (Bitmapfactoryoptions.outheight/imageh);    int xratio = (int) Math. ceil (Bitmapfactoryoptions.outwidth/imagew); if (Yratio > 1 | | xratio > 1) {if (Yratio > Xratio) {bitmapfactoryoptions.insamplesize = Yrat        Io        } else {bitmapfactoryoptions.insamplesize = Xratio;                                                                                          }                                                                                                                          } bitmapfactoryoptions.injustdecodebounds = False;//false---allowing the caller t    o Query the bitmap without has to allocate the memory for its pixels.    Bmap = Bitmapfactory.decodefile (Picture.getabsolutepath (), bitmapfactoryoptions);        if (bmap! = null) {//ivwcouponimage.setimagebitmap (BMAP);    return bmap; } return null;

B. Indirect use of soft references in case of boundary compression to avoid oom

/* Part of the code in the custom adapter */Public        View getView (int position, view Convertview, ViewGroup parent) {            File File = new file ( It.get (position));            Softreference<bitmap> SRF = Imagecache.get (File.getname ());            Bitmap bit = Srf.get ();            ImageView i = new ImageView (mcontext);            I.setimagebitmap (bit);            I.setscaletype (ImageView.ScaleType.FIT_XY);            I.setlayoutparams (New Gallery.layoutparams (WindowManager.LayoutParams.WRAP_CONTENT,                    WindowManager.LayoutParams.WRAP_CONTENT));            return i;        }

But we all know that after the completion of these functions decode, the end is through the Java layer of CreateBitmap to complete, need to consume more memory, if the picture is large, this way will still refer to the oom exception, so need to further processing:
A. The first way

InputStream is = This.getresources (). Openrawresource (R.DRAWABLE.PIC1);     Bitmapfactory.options options=new bitmapfactory.options ();     Options.injustdecodebounds = false;     Options.insamplesize = ten;   Width,hight is set to the original very one     Bitmap BTP =bitmapfactory.decodestream (is,null,options); if (!bmp.isrecycle ()) {         Bmp.recycle ()/   /recall the memory of the image         System.GC ()  //Reminder system timely recovery}

B. The second way

/*** read the picture of the local resource in the most memory-saving way * *  /public static Bitmap Readbitmap (context context, int resId) {          bitmapfactory.options opt = new Bitmapfactory.options ();          Opt.inpreferredconfig = Bitmap.Config.RGB_565;          Opt.inpurgeable = true;         Opt.ininputshareable = true;            Get the resource picture         InputStream is = Context.getresources (). Openrawresource (resId);             Return Bitmapfactory.decodestream (is,null,opt);     }

C. Garbage collection at the right time

if (bitmapobject.isrecycled () ==false)//If not recycled           bitmapobject.recycle

D. Optimizing heap memory allocation for Dalvik virtual machines
For Android platforms, the Dalvik JAVAVM used by its hosting layer can be optimized for processing from the present performance, eg we may consider manual interference in GC processing in the development of some large-scale games or resource-consuming applications, using The Settargetheaputilization method provided by the Dalvik.system.VMRuntime class can enhance the processing efficiency of the program heap memory.

Private final static floattarget_heap_utilization = 0.75f; You can call Vmruntime.getruntime () when the program OnCreate. Settargetheaputilization (target_heap_utilization);

As for why this is 0.75, the heap is the most memory-intensive part of the VM and is usually allocated dynamically. The size of the heap is not immutable, and there is usually an allocation mechanism to control its size. For example, the initial heap is 4M large, when 4M space is occupied more than 75%, the redistribution heap is 8M large, when 8M is occupied more than 75%, the allocation heap is 16M large. Upside down, when the 16M heap utilization is less than 30%, the size of the reduction is 8M large. The size of the heap, especially compression, usually involves a copy of the memory, so the size of the change heap has an adverse effect on efficiency.


E. Customizing how much memory is needed for our applications

Private final static int cwj_heap_size = 6* 1024* 1024; Set the minimum HEAP memory to 6MB size Vmruntime.getruntime (). Setminimumheapsize (Cwj_heap_size);

Image too large in Android causes memory overflow, OOM (OutOfMemory) Exception workaround

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.