Source: Reprinted from: http://mobile.51cto.com/abased-410796.htm
In Android apps, the most memory-intensive is the picture resource. And on Android, when reading bitmap bitmap, the stack size of the pictures in the virtual machine is only 8M, and if exceeded, a outofmemory exception occurs. Therefore, the memory optimization of the image is an important part of Android application development.
1, in time to recover bitmap memory
The bitmap class has a method recycle (), which can be seen from the method name meaning recycling. There is a question here, the Android system has its own garbage collection mechanism, can be collected from time to time not to use the memory space, of course, including bitmap space. Then why do you need this method?
The constructor of the bitmap class is private, so the developer cannot directly new out a bitmap object, only by instantiating a bitmap through the various static methods of the Bitmapfactory class. Looking closely at the source code of Bitmapfactory, you can see that the resulting bitmap object is eventually implemented by JNI invocation. So, after loading bitmap into memory, it contains two parts of the memory area. To put it simply, part of the Java part is part C. This bitmap object is allocated by the Java section, the system will be automatically recycled when not used, but the corresponding C available memory area, the virtual machine is not directly recoverable, this can only invoke the underlying function release. Therefore, the recycle () method needs to be called to release the memory of part C. From the source code of the bitmap class, it is also possible to see that the Recycle () method does invoke the Jni method.
So if you don't call recycle (), is there a memory leak? It's not. Each Android application runs in a separate process with independent memory, and if the entire process is applied itself or the system kills, the memory is freed and of course the C part of the memory is included.
Android's management of the process is very complex. Simply put, the process of the Android system is divided into several levels, and the system will kill some low-priority processes in case of insufficient memory to provide sufficient memory space for other processes. In the actual project development process, some developers will use Process.killprocess (Process.mypid ()) when exiting the program to kill their own process, but some applications will only use the call Activity.finish () method to shut down all activity.
Experience Sharing: Android phone users, depending on the habits, may have two ways to quit the entire application: one is to press the home button to go directly to the desktop, the other is from the application Exit button or press the back key to quit the program. So what is the difference between these two approaches from a system perspective? By pressing the home key, the application is not turned off, but it becomes a background application. By pressing the back key, the application is generally closed, but the process has not been killed, but it has become an empty process (the program itself does not take into account the special handling of the exit). The
Android system has done a lot of process management work, which has been able to meet the needs of users. Personally, the application does not need to manually kill its own process when exiting the app. For the process management of the application itself, give it to the Android system to handle it. What the application needs to do is to try to do the memory management work of the program itself.
In general, if you can get a reference to a bitmap object, you need to call Bitmap's recycle () method in a timely manner to free up the memory space bitmap occupies, instead of waiting for the Android system to release.
The following is a sample code fragment that frees bitmap.
if NULL &&! bitmap.isrecycled ()) { // bitmap.recycle (); NULL ; } System.GC ();
As can be seen from the code above, the Bitmap.recycle () method is used to reclaim the memory occupied by the bitmap, then the bitmap is empty, and finally the garbage collector of the system is called using System.GC () to recycle, which can be notified to the garbage collector as soon as possible. It is important to note that calling System.GC () does not guarantee that the recycling process will begin immediately, but only to expedite the recovery.
How to call the Recycle () method for recycling has been understood, then when to release bitmap memory more appropriate? In general, if the code is no longer required to use the bitmap object, it can be freed. Once the memory is freed, the bitmap object can no longer be used and, if used again, throws an exception. So be sure to release it when you're not using it. For example, if you use bitmap in an activity, you can recycle it in the activity's OnStop () or OnDestroy () method.
2. Catching exceptions
Because bitmap is eating large memory, in order to avoid the application in allocating bitmap memory when the OutOfMemory exception occurs after crash off, you need to pay special attention to instantiate the bitmap part of the code. In general, you must capture OutOfMemory exceptions in the code that instantiates bitmap.
Bitmap Bitmap = null try { instantiate Bitm AP bitmap = Bitmapfactory.decodefile ( path); catch (OutOfMemoryError e) { Span style= "color: #008000;" >// if (bitmap = null // If the instantiation fails, return the default bitmap object return Defaultbitmapmap; }
The outofmemory exceptions that may occur during the initialization of the bitmap object are captured here. If an outofmemory exception occurs, the app does not crash, but it gets a default bitmap diagram.
Experience sharing: Many developers are accustomed to capturing exception directly in their code. But for OutOfMemoryError, this is not captured. Because OutOfMemoryError is an error, not a exception. Just make a reminder to avoid writing the wrong code and not capturing OutOfMemoryError.
3. Cache Common Bitmap Objects
Sometimes, you may need to use the same image multiple times in an activity. For example, an activity will show a list of users ' avatars, and if the user does not set the avatar, a default avatar will be displayed, which is in the resource file of the application itself.
If you have a scenario like the one above, you can cache the same bitmap. If you do not cache, although you see the same picture file, but using the Bitmapfactory class method to instantiate the bitmap, is a different bitmap object. Caching avoids the waste of memory by avoiding creating multiple bitmap objects.
Experience Sharing: Web developers are familiar with caching techniques. In fact, during the development of Android application, the technology of caching is often used. Here the cache has two levels, one is the hard disk cache, and the other is the memory cache. For example, in the development of network applications, some data obtained from the network can be saved to the SD card, the next time directly from the SD card read, not read from the network, thereby saving network traffic. This is how the hard disk is cached. For example, applications often use the same object, or they can be cached in memory and read directly from memory when needed. This approach is memory caching.
4. Compress pictures
If the picture pixel is too large, the process of instantiating bitmap using the Bitmapfactory class method requires a memory space greater than 8M, and a OutOfMemory exception is bound to occur. What should be handled at this time? If this is the case, you can narrow the picture to reduce the use of memory in the process of loading the picture to avoid the occurrence of an exception.
You can use Bitmapfactory.options to set Insamplesize to narrow your picture. The property value insamplesize indicates that the thumbnail size is one of a fraction of the original picture size. That is, if the value is 2, then the width and height of the thumbnail are taken to be 1/2 of the original image, and the image size is 1/4 of the original size.
If you know that the picture's pixels are too large, you can narrow it down. So how do you know the picture is too big?
using Bitmapfactory.options to set Injustdecodebounds to True, then use DecodeFile () and other methods, will not really allocate space, that is, the decoded bitmap is null, However, you can calculate the width and height of the original image, that is, Options.outwidth and options.outheight. With these two values, you can tell if the picture is too large.
bitmapfactory.options opts = new Bitmapfactory.options (); // set Injustdecodebounds to True Span style= "color: #000000;" > Opts.injustdecodebounds = true ; // Use the DecodeFile method to get the width and height of the picture Bitmapfactory.decodefile (path, opts); // print out the width and height of the picture LOG.D ( "Example", Opts.outwidth + "," + opts.outheight);
Experience Sharing: If the program is the source of the picture is the package of resources, or the picture on its own server, the size of the picture is the developer can adjust, then generally speaking, only need to pay attention to the use of the picture is not too large, and pay attention to the quality of the code, timely collection of bitmap objects, Can avoid the occurrence of outofmemory anomalies.
If the picture of the program comes from outside, this time special need to pay attention to the occurrence of outofmemory. One is that if the loaded picture is larger, it needs to be narrowed first, and the other is to catch the exception and avoid the program crash.
"Turn" Android Development bitmap memory optimization in detail