Android handle several picture OOM Methods Summary (recommended)

As we all know, each Android application at run-time memory has a certain limit, size limit is usually 16MB or 24MB (platform dependent). Therefore, when developing applications that require special attention to their own memory usage, but in general most memory consumption amount of resources, usually images, audio files, video files and other multimedia resources; Android system for audio, video and other resources to do the side to resolve it playback processing, the use does not put the entire file is loaded into memory, the memory overflow error (hereinafter referred to as OOM) generally does not occur, so they temporarily in memory consumption issues beyond the scope of this article. This article focuses on is the memory consumption problem of the picture, if you want to develop is a picture viewer application, such as Android system comes with applications like Gallery, this problem will become particularly prominent; if you are currently developing Shopping clients, sometimes not handled properly will encounter this problem.

Currently encountered OOM scene, nothing less than the following cases, but either case, problem-solving ideas are the same.

(1) display a single image, image file size is reached when the level of 3000 * 4000;

(2) a large number of pictures and other disposable loading or Gallery ListView control;

Knowledge Introduction

1. Color Model

There is a common color model RGB, YUV, CMYK, etc., used in most of the images are in RGB model API, Android, too; in addition, there are included in the Android Alpha transparency color model, that is ARGB. About color model more detailed information temporarily outside the scope of this article.

 \\

2. The digitally encoded color values ​​computer

Without considering the transparency, the color value of a pixel in the computer representation of the following three:

(1) floating point code: for example float: (1.0, 0.5, 0.75), each color component half and a float field, wherein the component value of 1.0 indicates all red or all green or all blue;

(2) 24-bit coded integer: for example, 24-bit: (255, 128, 196), each of 8 bits for each color component, a range of 0-255, where 255 represents the value of all red or all of the components green or all blue;

(3) 16-bit coded integer: for example, 16-bit: (31, 45, 31), the first and third color components each accounted for 5, in the range 0-31, the second color component accounted 6 in the range 0-63;

In Java, float type variables accounted for 32, int type variables accounted for 32, short, and variable of type char are 16-bit, it can be seen that a coded representation of the pixel color, memory footprint floating point number is 96 or 12 bytes; and represents an integer of 24 bits encoding method, as long as a variable of type int, 4 bytes (eight empty high, the lower 24 bits used to represent the color); 16-bit integer representation encoding, as long as a short type variable, 2 bytes; therefore be seen that the color coding in integer representation values, can greatly save memory, of course, some of the color quality will be relatively low. Bitmap acquired in Android generally employed when the integer encoding.

Two or more integer coded notation, R, G, B components each sequence may be an RGB or BGR, Android in the order of RGB is used herein to follow this order are also discussed. 24-bit integer representation, since the R, G, B 8 bits for each component, but also sometimes in the industry to refer to this information RGB888; similarly, in the 16-bit integer representation, R, G, 5,6,5-bit B components are accounted for, with regard to RGB565 to refer to this information.

Now consider transparency color coding, in fact, with non-transparent mode as encoding: 24 encoding integer int type variables using the RGB model, which is just idle 8 for placing high transparency components, wherein 0 represents full transparency, 255 is fully opaque; in the order of a, R, G, B, it can be summarized in this situation ARGB8888; the 16-bit coded integer type variable RGB model uses short, each component adjusted to 4 are occupied by several , it can just vacated four encoded transparency values; in order of a, R, G, B, it can be summarized ARGB4444 this situation. Recall BitmapConfig class Android, there ARGB_8888, ARGB_4444, RGB565 and other constants can now know the meaning of what they represent. But you can also calculate a picture in memory size may occupy, such as the use ARGB_8888 coding load a 1920 * 1200 picture, probably will take up 1920 * 1200 * 4/1024/1024 = 8.79MB memory.

3.Bitmap stored in the memory area

http://www.7dot9.com/2010/08/android-bitmap%E5%86%85%E5%AD%98%E9%99%90%E5%88%B6/ do an article on the Android memory limit problem some discussion, the authors believe Bitmap object on the stack by reference to point to heap Bitmap object, a Bitmap object in turn corresponds to the external storage using native image, in fact, using a byte [] to store the memory space. But in order to ensure the success of the external memory is allocated, it should ensure that part of the current allocated memory plus memory allocation for the current value, the maximum memory size can not exceed the value of the current heap, and memory management entirely on the external memory as the current heap.

Object reference type 4.Java

(1) strong reference (StrongReference) If an object has a strong reference, and that the garbage collector will never recover it. When the memory space is insufficient, Java Virtual Machine would rather throw OutOfMemoryError errors, abnormal termination of the program, it will not recover by random objects that have strong references to solve the problem of insufficient memory.

(2) soft references (SoftReference) If an object has only soft references, the memory space is sufficient, the garbage collector does not reclaim it; if the memory space is insufficient, it will reclaim the memory of these objects. As long as the garbage collector does not reclaim it, the object can be used by the program.

(3) weak reference (WeakReference) weak references and soft references that difference: only a weak reference objects have more short life cycle. In the process of the garbage collector thread scans memory area under its jurisdiction, once the objects found only a weak reference, regardless of the current memory space is sufficient or not, will reclaim its memory.

(4) virtual reference (PhantomReference) "Virtual Reference" by definition, is non-existent, and several other references are different, virtual reference and does not determine the object's life cycle. If an object holds only a phantom reference, and then it does not have any references, they are likely to be garbage collected at any time.

Solve common scenarios of OOM

Android memory limit is the application of a system-wide limit, as an application developer layer, there is no way to completely eliminate this limitation, but by some means to the rational use of memory, thus avoiding this problem. Here are some common methods of personal summary:

(1) to the image buffer memory, cache memory uses soft references, rather than every time the new use are loaded into memory;

(2) adjust the image size, the limited screen size of a mobile phone, a display area assigned to the image itself is even smaller, the image size may sometimes make the appropriate adjustments;

(3) employ low memory footprint encoding, such Bitmap.Config.ARGB_4444 Bitmap.Config.ARGB_8888 more economical than the memory;

(4) timely recovery image, if a Bitmap object references a lot, but they do not need to apply simultaneously display all the pictures, you can not use a temporary Bitmap object timely recovery of lost;

(5) custom heap memory allocation size, heap memory allocation optimization Dalvik virtual machine;

This paper will make the presentation and analysis of the first four ways.

Demonstration test instructions

To illustrate scenes appear and solve OOM OOM way, I made a --OomDemo Android application to demonstrate the basic situation of this application are described below:

(1) The application shows a gallery, the gallery load pictures, gallery of pictures adapter in the incoming path instead of pictures of the object itself, adapter dynamically loaded images;

(2) demonstrate the use of pre-stored images to the next cache sdcard directory, the file names are a.jpg, b.jpg ... r.jpg, a total of 18;

(3) Photo size 1920 * 1200 jpg image, the file size in the range of 423KB-1.48MB;

(4) Operating environment: Simulator Version --android2.2 system 320 --480 * screen size; Moto Defy - 2.3.4 version CM7 system 480 --854 * screen size;

(5) Basic structure of FIG procedure:

 \

Description result presentation

1. a demo

Firstly, the easiest way to load pictures without any image cache, resize or recycled, SimpleImageLoader.class is to assume this responsibility. Code Load picture part as follows:

@Override

public Bitmap loadBitmapImage(String path) {

       return BitmapFactory.decodeFile(path);

}

@Override

public Drawable loadDrawableImage(String path) {

       return new BitmapDrawable(path);

}

The results demonstrate: in the picture on the simulator can only load Zhang 1-3, after OOM error will appear; error does not appear on the Defy; because of the two different memory limit, Defy is running on a third-party ROM, memory allocation there 40MB. When the gallery each display a picture, get a picture to be re-resolved, although it is never a mistake on Defy, but increase the amount of pictures, the GC is not recovered in time, or there may be OOM.

2. Demonstration of two

To add a picture to load the soft reference cache, each time the object images acquired images from the cache, if the cache does not exist, will load pictures from Sdcard, and add the object cache. While soft objects referenced GC also help recover them when out of memory. ImageLoaderWithCache.class in charge of this responsibility, the key code is as follows:

private HashMap<String, SoftReference<Bitmap>> mImageCache;

       @Override

       public Bitmap loadBitmapImage(String path) {

              if(mImageCache.containsKey(path)) {

                     SoftReference<Bitmap> softReference = mImageCache.get(path);

                     Bitmap bitmap = softReference.get();

                     if(null != bitmap)

                            return bitmap;

              }

              Bitmap bitmap = BitmapFactory.decodeFile(path);

              mImageCache.put(path, new SoftReference<Bitmap>(bitmap));

              return bitmap;

       }

       @Override

       public Drawable loadDrawableImage(String path) {

              return new BitmapDrawable(loadBitmapImage(path));

       }

The results demonstrate: in the simulator, can load multiple cache 1-2 is not no pictures, but still there will be OOM; never wrong on the Defy. Since this used pictures are relatively total memory, when the GC had time to recover soft reference object, you have to apply beyond the remaining amount of memory space, so still not able to completely avoid OOM. If loaded into a large number of small images, such as 100 * 100 specifications, soft reference cache role might play out. (This assumption can be further tests to prove it)

3. demonstrate three

To further avoid OOM, in addition to the cache, but also can be compressing the picture, further saving memory, resize pictures in most cases does not affect the performance of the applied force. ImageLoaderWithScale.class is responsible for this duty, adjust the size of the code is as follows:

BitmapFactory.Options options = new BitmapFactory.Options();

       options.inJustDecodeBounds = true;

       BitmapFactory.decodeFile(path, options);

       if (options.mCancel || options.outWidth == -1 || options.outHeight == -1) {

              Log.d(“OomDemo”, “alert!!!” + String.valueOf(options.mCancel) + ” ” + options.outWidth + options.outHeight);

              return null;

       }

       options.inSampleSize = Util.computeSampleSize(options, 600, (int) (1 * 1024 * 1024));

       Log.d(“OomDemo”, “inSampleSize: ” + options.inSampleSize);

       options.inJustDecodeBounds = false;

       options.inDither = false;

       options.inPreferredConfig = Bitmap.Config.ARGB_8888;

       Bitmap bitmap = BitmapFactory.decodeFile(path, options);

The results demonstrate: In the above code, the first decoded picture border, without the need to give the premise Bitmap object image can be obtained a high width (width and height values ​​are set to two options.outHeight options.outWidth and attributes). ComputeSampleSize parameters of this method are "desired image analysis BitmapFactory.Options", "picture adjusted minimum width or height value", "Image memory footprint adjusted limit." Binding original picture aspect, the method may calculate an adjustment ratio, then this scaling original image and loaded into memory, the picture memory consumed at this time does not exceed the pre-specified size. In the simulator, the memory size limit of 1 share pictures * 1024 * 1024, more than uncompressed outdated able to load more pictures, but there will still be OOM; if the share memory size limit Image 0.5 * 1024 * 1024, You can complete all loaded images. So resize the picture was able to effectively save memory. You can not go wrong in Defy the same reason.

4. demonstrate four

In some cases, severely reduce the image will still affect the appearance of the application, it is necessary to show the picture in as little as possible down picture premise, this time to manually recover the picture becomes particularly important. In class ImageLoaderWithRecyle.class, the picture will be increased by a method for recovering resources:

@Override

       public void releaseImage(String path) {

              if(mImageCache.containsKey(path)) {

                     SoftReference<Bitmap> reference = mImageCache.get(path);

                     Bitmap bitmap = reference.get();

                     if(null != bitmap) {

                            Log.d(“OomDemo”, “recyling ” + path);

                            bitmap.recycle();

                     }

                     mImageCache.remove(path);

              }

       }

The results demonstrate: Image compression limit remains at 1 * 1024 * 1024, in the adapter, the timely call releaseImage method, no need to recover the picture. At this time, the simulator has never appeared OOM, so generally speaking, various means integrated cache, resize, recycling, or to avoid the OOM.

summary

This article describes the soft reference cache, resize, recycling and other means to avoid OOM, in general, the effect is obvious. However, the actual application scenario, the application does not want the picture demonstrated in this article as simple, sometimes images can come from a network resource, then you need to fit loaded asynchronously to download pictures and displayed by the callback method; sometimes still image resources the need for additional modifications add borders, add text, etc., so even after the image is loaded to do another deal.

In addition, as I have capacity constraints and time constraints, there are many imperfections of the paper. For example, the understanding of the Android memory allocation is not deep and did not thoroughly explain the memory usage of Bitmap; custom heap memory allocation size, optimized Dalvik virtual machine to solve the OOM method of heap memory allocation, the paper did not give the presentation; then For example, in the above demonstration test, there is no detailed information about the memory usage of intuitive display the image in the form of out; there are a number of pictures used in the demo is too small, a single specification, test environment less than normal, all failed to carry out more rigorous scientific the comparative tests, missing some surprises. Finally, welcome to explore, communicate and make recommendations.

Reproduced in: https: //www.cnblogs.com/wangzehuaw/p/4307996.html

Guess you like

Origin blog.csdn.net/weixin_33794672/article/details/93778437