Android Basics Getting Started tutorial--8.2.2 bitmap caused by oom problem
tags (space delimited): Android Basics Getting Started Tutorial
Introduction to this section:
In the last section, we have learned the basic usage of bitmap, and this section we are going to explore the bitmap of the oom problem,
In the actual development of people may have encountered, or have not encountered because bitmap caused by the oom problem, this section we
Come around this topic to learn about what is oom, why it causes oom, improve the bitmap caused by
Oom Problem ~
1. What is Oom? Why does it cause oom?
A:out of memory, we all know that the Android system will allocate a separate workspace for each app,
or assign a separate Dalvik virtual machine so that each app can run independently without affecting each other! and Android for each
The Dalvik virtual machine will have a maximum memory limit, if the current memory usage plus the memory resources we requested exceed this limit
, the system will throw an OOM error! In addition, there is no confusion with RAM, and there is more than 1G of memory left in the current RAM, but Oom will still happen! Don't pull the RAM (physical memory) and Oom together! In addition, RAM is not enough, it is to kill the application, and not just the Oom!
and the maximum memory standard in this Dalvik, different models are not the same, can be called:
ActivityManager activityManager = (ActivityManager)context.getSystemService(Context.ACTIVITY_SERVICE);Log.e("HEHE","最大内存:" + activityManager.getMemoryClass());
>
Get the normal maximum memory standard, or type directly at the command line:
adb shell getprop | grep dalvik.vm.heapgrowthlimit
You can also open the system source/system/build.prop file, look at the information in this section of the file to obtain:
dalvik.VM .heapstartsize =8 Mdalvik.VM .heapgrowthlimit = 192 mdalvik.VM .heapsize =512 mdalvik.VM .heaptargetutilization = 0.75 dalvik.VM .heapminfree =2 mdalvik.VM .heapmaxfree =8 m
There are three areas of concern: the initial size of the Heapstartsize heap memory, the maximum heap of heapgrowthlimit standard applications
Memory size, heapsize is the maximum heap memory size that is set for apps that use Android:largeheap!
I tried this here. Normal maximum memory allocation criteria for the first few models:
You can also try your own machine.
Okay, no, it's about the problem of Oom, it's got to be here, and then to the memory management that piece, but a big one,
Now still gnawing ... Let's take a look at some tips to avoid bitmap oom!
2. Avoid bitmap-induced Oom Tips Summary 1) Using low memory consumption of the encoding method
The previous section says bitmapfactory.options This class, we can set the Inpreferredconfig property under it,
Default is Bitmap.Config.ARGB_8888, we can modify into Bitmap.Config.ARGB_4444
Bitmap.config argb_4444: Four bits per pixel, which is a=4,r=4,g=4,b=4, then one pixel takes up 4+4+4+4=16 bit.
Bitmap.config argb_8888: Eight bits per pixel, which is a=8,r=8,g=8,b=8, then one pixel takes up 8+8+8+8=32 bit.
By default, argb_8888 is used, which is 4 bytes per pixel!
2) Image compression
The same is bitmapfactory.options, we set the zoom factor through the insamplesize , such as Write 2, that is, the length of the width into the original 1/2, the picture is the original 1/4, if not scaled, set to 1! But not blindly compression, after all, this value is too small
, the picture will be very blurry, and to avoid the tensile deformation of the picture, so we need to calculate the dynamic in the program, this
Insamplesize the appropriate value for the option, and in the options there is another method:injustdecodebounds, set this parameter to
True, Decodefiel does not allocate memory space, but can calculate the length and width of the original image, calling
Options. outwidth/outheight Get the width and height of the picture, and then through a certain algorithm, you can get the appropriate
Insamplesize, thank you for the code from the street God --from Yang blog!
Public Static int caculateinsamplesize(Bitmapfactory.options Options,intReqwidth,intReqheight) {intwidth = options.outwidth;intHeight = options.outheight;intInsamplesize =1;if(Width > Reqwidth | | height > reqheight) {intWidthradio = Math.Round (Width *1.0F/reqwidth);intHeightradio = Math.Round (Height *1.0F/reqheight); Insamplesize = Math.max (Widthradio, Heightradio); }returnInsamplesize; }
Then use the following method:
Bitmapfactory. Optionsoptions = new Bitmapfactory. Options();Options. Injustdecodebounds= True;//Set this property be sure to remember to set the value to FalseBitmap Bitmap = null;Bitmap = Bitmapfactory. DecodeFile(URL, options);Options. Insamplesize= Computesamplesize (Options, -, -);Options. Inpreferredconfig= Bitmap. Config. ARGB_4444; / * The following two fields need to be combined with * /Options. Inpurgeable= True;Options. Ininputshareable= True;Options. Injustdecodebounds= False;try {bitmap = Bitmapfactory. DecodeFile(URL, options);} catch (OutOfMemoryError e) {Log. E(TAG,"OutOfMemoryError");}
3. Timely recovery of images
If you reference a large number of bitmap objects, the app does not need to display all the pictures at the same time. A bitmap object that can be temporarily unused
Timely recovery. For some scenarios that explicitly know about picture usage, you can proactively recycle recycling, such as a picture of a guided page, using
Finish on the recycle, frame animation, load a picture, draw one, release a piece! Load when used, do not display when null or recycle! is directly placed
For example: Imageview.setimageresource (0);
In some cases, however, certain images are loaded repeatedly, released, reloaded, etc., and inefficient things ...
4. Other methods
The following methods, I have not used, we can check the relevant information:
1. Simple management of picture resources by SoftReference reference method
Build a SoftReference hashmap.
When using the picture, first query the HashMap whether there is SoftReference, softreference in the picture is empty,
If empty, load the picture to SoftReference and add the HashMap.
There is no need to explicitly handle the collection and release of images in the code, and the GC automatically handles the release of resources.
This approach is simple and practical, and can avoid the inefficiency of the previous method's repeated load release. But it's not optimized enough.
Example code :
Privatemap<string, softreference<bitmap>> ImageMap =NewHashmap<string, softreference<bitmap>> (); PublicBitmapLoadBitmap(Final String imageurl,final imagecallback imagecallback) {softreference<bitmap> reference = ImageMap.Get(IMAGEURL);if(Reference! =NULL) {if(Reference.Get() !=NULL) {returnReference.Get(); }} final Handler Handler =NewHandler () { Public void Handlemessage(Final android.os.Message msg) {//Add to cacheBitmap Bitmap = (Bitmap) msg.obj; Imagemap.put (IMAGEURL,NewSoftreference<bitmap> (Bitmap));if(Imagecallback! =NULL) {Imagecallback.getbitmap (bitmap); } } };NewThread () { Public void Run() {Message message = Handler.obtainmessage (); Message.obj = Downloadbitmap (IMAGEURL); Handler.sendmessage (message); }}.start ();return NULL; }//download pictures from the internet PrivateBitmapDownloadbitmap(String imageUrl) {Bitmap Bitmap =NULL;Try{bitmap = Bitmapfactory.decodestream (NewURL (IMAGEURL). OpenStream ());returnBitmap; }Catch(Exception e) {E.printstacktrace ();return NULL; } } Public Interfaceimagecallback{voidGetbitmap (Bitmap Bitmap); }
2.LruCache + SD Cache mode
From the Android 3.1 version, the official also provided the LRUCache to perform the cache processing when the size of the storage image is greater than LRUCache
Set the value, then the most recent use of the least number of images will be recycled, the system will automatically free memory!
Examples of Use :
Steps:
1) To set the memory size of the cached image, I set this to 1/8 of the phone memory,
How to get the phone memory: int maxmemonry = (int) (Runtime.getruntime (). MaxMemory ()/1024);
2) The key-value pairs in the LRUCache are URL and corresponding images respectively.
3) rewrite a method called sizeof, which returns the number of pictures.
PrivateLrucache<string, bitmap> Mmemorycache;Private lrucacheutils() {if(Mmemorycache = =NULL) Mmemorycache =NewLrucache<string, bitmap> (Maxmemonry/8) {@Override protected int sizeOf(String key, Bitmap Bitmap) {//Override this method to measure the size of each picture, returning the number of pictures by default. returnBitmap.getrowbytes () * Bitmap.getheight ()/1024x768; }@Override protected void entryremoved(BooleanEvicted, String key, Bitmap OldValue, Bitmap newvalue) {LOG.V ("Tag","Hard cache are full, push to soft cache"); } }; }
4) The following methods are to empty the cache, add pictures to the cache, get pictures from the cache, and remove them from the cache.
Removing and clearing the cache is something that must be done, because the image cache is improperly handled to report a memory overflow, so be sure to pay attention.
Public void ClearCache() {if(Mmemorycache! =NULL) {if(Mmemorycache.size () >0) {LOG.D ("Cacheutils","Mmemorycache.size ()"+ mmemorycache.size ()); Mmemorycache.evictall (); LOG.D ("Cacheutils","Mmemorycache.size ()"+ mmemorycache.size ()); } Mmemorycache =NULL; } } Public synchronized void Addbitmaptomemorycache(String key, Bitmap Bitmap) {if(Mmemorycache.get (key) = =NULL) {if(Key! =NULL&& Bitmap! =NULL) Mmemorycache.put (key, bitmap); }ElseLOG.W (TAG,"The res is aready exits"); } Public synchronizedBitmapGetbitmapfrommemcache(String key) {Bitmap BM = mmemorycache.get (key);if(Key! =NULL) {returnBm }return NULL; }/** * Remove Cache * * @param key */ Public synchronized void Removeimagecache(String key) {if(Key! =NULL) {if(Mmemorycache! =NULL) {Bitmap BM = mmemorycache.remove (key);if(BM! =NULL) bm.recycle (); } } }
The above content is excerpted from--the memory cache technology of image cache LRUCache, soft reference
This section summarizes:
This section explains the cause of the oom problem, but also summarizes some of the online to avoid bitmap caused by the Oom
Some of the programs, because the company does the app is the map class, rarely involved in the picture, so I did not encounter the problem of Oom,
So it's not very familiar with the follow-up in the advanced course of memory management, we will slowly tangled this oom problem, good,
This section is here, thank you ~
Reference Documents :
Analysis and solution of oom problem in Android application
Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.
Android Basics Getting Started tutorial--8.2.2 bitmap caused by oom problem