OOM: Memory leaks can cause a number of problems: 1. Application delays and slow response times (JVMS frequently trigger GC when memory usage is high) 2. Disappear (The more memory your program takes up, the more likely it is to get killed in the background. On the other hand, the smaller the memory footprint, the longer the time in the background.) 3. Limited heap memory, originally only 16M 2. Memory size consumption, etc., varies by device, operating system level, screen size 3. The program cannot be directly controlled 4. Background multitasking is supported 5. Running on virtual machine 5R: This article mainly uses the following 5R method to optimize ANDROID memory: The first thing you’ll need to know is how much memory your app is using, and it’s going to cost you a lot of money. 例 句 : Review your program to see if the design or code doesn’t make sense. Reduce: Reduce means to Reduce. Directly reducing memory usage is the most effective way to optimize. Here are some ways to reduce memory usage: Bitmap: Bitmap is a big user of memory, and most OOM crashes occur when manipulating bitmaps. Here are some ways to handle images: Image display: We need to load the image size as required. For example, load thumbnails in a list for preview only. Only when the user clicks on a specific item and wants to see the details, then another fragment/activity/dialog box is launched to display the entire image size: Using ImageView directly to display a bitmap consumes a lot of resources, especially if the image is too large, it may crash. InSampleSize is set with bitmapFactory.options to reduce system resource requirements. Attribute value inSampleSize indicates that the thumbnail size is a fraction of the original size. That is, if the value is 2, the width and height of the extracted thumbnail are 1/2 of the original size, and the image size is 1/4 of the original size.

1 BitmapFactory.Options bitmapFactoryOptions = new BitmapFactory.Options(); 2 bitmapFactoryOptions.inJustDecodeBounds = true; 3 bitmapFactoryOptions.inSampleSize = 2; 5 // After setting inJustDecodeBounds to true, decodeFile does not allocate space, that is, BitmapFactory decoding the Bitmap is Null, the original image can be calculated the length and width of 6 options. InJustDecodeBounds = false; 7 Bitmap bmp = BitmapFactory.decodeFile(sourceBitmap, options); Image pixel: There are four attributes for an image in Android: ALPHA_8:1byte memory for each pixel ARGB_4444:2byte memory for each pixel ARGB_8888:4byte memory for each pixel (default) RGB_565: The default Android color mode is ARGB_8888. This color mode is the most delicate and has the highest display quality. But again, it takes up the most memory. So use RGB_565 (565 has no transparency property) if the image effect is not particularly high, as follows: [Java] View PlaincopyPrint? 8 publicstaticBitmapreadBitMap(Contextcontext, intresId) { 9 BitmapFactory.Optionsopt = newBitmapFactory.Options(); 10 opt.inPreferredConfig = Bitmap.Config.RGB_565; 11 opt.inPurgeable = true; 12 opt.inInputShareable = true; InputStreamis = context.getResources().openRawResource(resId); 15 returnBitmapFactory.decodeStream(is, null, opt); 16}Copy the code

Image recycling: After using Bitmap, you need to call bitmap.recycle () to release the memory space occupied by Bitmap without waiting for the Android system to release the memory space. Here is an example code snippet for releasing a Bitmap.

18 if(bitmap! = null && ! IsRecycled () {19 // Recycle and set it to null 20 bitmap.recycle(); 21 bitmap = null; 22 } 23 System.gc(); [Java] View PlaincopyPrint: [Java] View PlaincopyPrint? 24 Bitmap bitmap = null; DecodeFile (path); decodeFile(path); decodeFile(path); 28} catch (OutOfMemoryError e) {29 30} 31 if (bitmap == null) {32 // Return the default bitmap object if the instantiation fails. 33 Return defaultBitmapMap; 34}Copy the code

Modify object reference type: Reference type: References are classified into four levels in descending order: Strong reference > Soft reference > Weak reference > Virtual reference. Strong reference: Object Object =new Object () Object is a strong reference. When running out of memory, the Java virtual machine would rather throw outofMemoryErrors to abort the program than randomly recycle objects with strong references to resolve the memory problem. A SoftReference is reclaimed only when the memory is insufficient. It is usually used for caching. When memory reaches a threshold, GC reclaims it; Weakreferences Weakly referenced objects have a shorter life cycle. When the garbage collector thread scans the memory area under its control, once it finds an object with only weak references, it reclaims its memory regardless of whether the current memory space is sufficient. A virtual reference, as its name implies, is a virtual reference. Unlike other references, a virtual reference does not determine the life cycle of an object. If an object holds only virtual references, it can be garbage collected at any time, just as if there were no references at all. Note: Bitmap caching of SoftReference or WeakReference is not recommended. Since Android2.3 (API Level 9), the garbage collector focuses more on collecting soft/weak references, so the following can be ignored. In the development of Android applications, in order to prevent memory overflow, soft reference and weak reference technology can be applied as far as possible when dealing with some objects that occupy large memory and have a long declaration cycle. Using soft references as an example (weak references are used in a similar way to soft references) : Assume that our application uses a large number of default images, and that these images are used in many places. If you try to read the picture every time, because the reading of the file requires hardware operation, the speed is slow, resulting in low performance. So we thought about caching the images and reading them directly from memory when needed. However, because images occupy a large memory space, caching many images requires a large amount of memory, which may be prone to OutOfMemory exceptions. At this point, we can consider using soft reference techniques to avoid this problem. Start by defining a HashMap that holds soft reference objects.

35 private Map<String, SoftReference<Bitmap>> imageCache = new HashMap<String, SoftReference<Bitmap>>(); Define a method that holds a soft reference to a Bitmap into a HashMap. [java] view plaincopyprint? 36 Public void addBitmapToCache(String path) {37 // Strong reference to the Bitmap object 38 Bitmap Bitmap = bitmapFactory.decodefile (path); 40 SoftReference<Bitmap> softBitmap = new SoftReference<Bitmap>(Bitmap); 42 imageCache. Put (path, softBitmap); 42 imageCache. 43} // Obtain a Bitmap object using the get() method of SoftReference. 44 Public Bitmap getBitmapByPath(String path) {45 // Obtain the SoftReference Bitmap object from the cache. 46 SoftReference<Bitmap> softBitmap = imageCache.get(path); 48 if (softBitmap == null) {49 return null; Getbitmap () = softbitmap.get (); getbitmap = softbitmap.get (); 53 return bitmap; 54}Copy the code

After soft reference is used, the memory space of these cached image resources can be freed before OutOfMemory exception occurs, thus avoiding the memory limit and avoiding Crash. Note that the GET method provided by the SoftReference class returns a strong reference to the Java object before the garbage collector collects the object, and once the garbage thread collects the Java object, the GET method returns NULL. Therefore, in the code that obtains soft reference objects, it is important to check whether the object is null, so that NullPointerException does not occur and the application crashes. When do you use soft references and when do you use weak references? Personally, if you just want to avoid OutOfMemory exceptions, you can use soft references. If you are more concerned about the performance of your application and want to reclaim some memory-consuming objects as quickly as possible, you can use weak references. It can also be judged by how often an object is used. If the object is likely to be used frequently, use soft references. If it is more likely that the object will not be used, use weak references. In addition, WeakHashMap is similar to weakreference. WeakHashMap For a given key, the existence of its mapping does not prevent the garbage collector from collecting the key, after which its entries are effectively removed from the map. WeakHashMap uses ReferenceQueue to implement this mechanism. Static int intVal = 42; static int intVal = 42; Static String strVal = “Hello, world! ; The compiler generates a method called Clinit to initialize the class, which is executed when the class is first used. The intVal method assigns 42 to intVal, and then a reference to the constant table in the class to strVal. When these values are used later, they will be looked up in the member variable table. Static final int intVal = 42; static final int intVal = 42; static final int intVal = 42; Static final String strVal = “Hello, world! ; Classes no longer need the Clinit method because constants are saved directly to the class file when member variables are initialized. Code that uses intVal is replaced directly with 42, and code that uses strVal points to a string constant instead of a member variable. Declaring a method or class final does not improve performance, but it helps the compiler optimize the code. For example, if the compiler knows that a getter method will not be overloaded, it makes an inline call to it. You can also declare local variables as final, and again, there is no performance benefit. Using “final” only makes local variables look cleaner (but there are times when this is necessary, such as when anonymous inner classes are used). Static methods instead of virtual methods If you don’t need to access the fields of an object, making a method static will speed up calls by 15 to 20 percent. This is also good practice, as you can see from the method declaration that calling the method does not require updating the object’s state. Avoid using static member variables to reference resource-consuming instances, such as Context, because references to a Context extend beyond its lifetime, causing the Context to leak. So use the Application Context type as much as possible. You can call the Context. GetApplicationContext () or Activity. GetApplication () easy to get the Application object. The most common example of avoiding unnecessary object creation is using StringBuffer instead of String when you are manipulating a String frequently. For all combinations of all basic types: Int arrays are better than Integer arrays, which also encapsulates the basic fact that two parallel int arrays perform much better than arrays of (int,int) objects. In general, this is to avoid creating ephemeral temporary objects. Reducing object creation reduces garbage collection, which in turn reduces the impact on the user experience. Avoiding internal Getters/Setters Virtual method calls are much more expensive than direct field access in Android. It usually makes sense to use Getters and Setters in a public interface based on object-oriented language practice, but direct access is appropriate in a class where fields are frequently accessed. A common rule of thumb is that floating-point numbers are twice as slow as integers on Android devices. Using the entity analogy interface well suppose you have a HashMap object, you can declare it as a HashMap or Map: Map map1 = new HashMap(); HashMap map2 = new HashMap(); Which is better? Traditionally, a Map is better because you can change its implementation class, as long as the class inherits from the Map interface. The conventional wisdom is true for traditional programs, but it does not apply to embedded systems. Calling a reference to an interface takes twice as long as calling a reference to an entity class. There is little value in using a HashMap if it fits perfectly into your program. If you are unsure about something, avoid using Map and leave the rest to the refactoring provided by the IDE. (The public API is the exception, of course: a good API often sacrifices some performance.) Avoiding enumerations is very convenient, but unfortunately it compromises execution speed and increases file size considerably. Using enumerated variables makes your API better and provides compile-time checks. So in general you should definitely choose enumerated variables for the public API. But when there are performance limitations, you should avoid doing this. The for loop accesses member variables much more slowly than local variables, as in the following code:

55 for(int i =0; i < this.mCount; I++) {} never call any method in the second condition of for, as in the following: [Java] view plaincopyprint? 56 for(int i =0; i < this.getCount(); [Java] view plaincopyprint? 57 int count = this.mCount; / int count = this.getCount(); 58 for(int i =0; i < count; I++) {} for-each syntax introduced in java1.5. The compiler stores references to the array and the length of the array in local variables, which is great for accessing array elements. But the compiler also generates an extra store operation on a local variable (such as variable A in the example below) in each loop, which is 4 bytes longer and slightly slower than normal loops: 59 for (Foo a: mArray) {60 sum += a.msplat; 61}Copy the code

Knowing and using libraries to select Library code instead of rewriting it yourself, in addition to the usual reasons, is probably better than the equivalent of the best Java code generated in the JIT, given that the Library methods are replaced by assembly code calls when the system is idle. When working with strings, don’t be stingy with special implementation methods like String.indexof (), string.lastIndexof (), etc. These methods are implemented using C/C++ and are 10 to 100 times faster than Java loops. The System. Arraycopy method performed a self-coded loop nine times faster on the Nexus One with the JIT. The Formatter class in the Android.text. format package provides methods for converting IP addresses and file sizes. The DateFormat class, which provides a variety of time conversions, is a very efficient method. TextUtils class for string handling Android offers a simple and practical TextUtils class, if the process is simple without thinking about the content of the regular expression might as well try this one on Android. The text. The TextUtils high-performance MemoryFile class, Many people complain that Android is not very good at handling low-level I/O. If you don’t want to use the NDK, you can use the MemoryFile class for high-performance file reads and writes. Where do memoryfiles fit in? For I/O operations that require frequent operations, mainly I/O operations related to external storage, memoryfiles map files on NAND or SD cards to memory for modification in segments, thus replacing ROM or SD cards with high-speed RAM, which naturally improves performance. It also reduces battery consumption for Android phones. This class implements few functions, inherits directly from Object, and executes directly in C via JNI. Reuse: Reuse to reduce memory consumption. The core idea is to reuse existing memory resources and avoid creating new ones. The most typical uses are caches and pools. Bitmap caching:

Bitmap caches are divided into two types: memory caches and hard disk caches. Memory cache (LruCache) : Memory cache provides fast Bitmap access at the expense of valuable application memory. The system-provided LruCache class is ideal for caching Bitmap tasks, storing recently referenced objects in a strongly-referenced LinkedHashMap and releasing recently infrequently used objects when the cache exceeds a specified size. Note: A very popular memory cache implementation was a Bitmap cache of SoftReference or WeakReference, but it is no longer recommended. Since Android2.3 (API Level 9), the garbage collector focuses more on collecting soft/weak references, which makes the above scheme quite ineffective. DiskLruCache: An in-memory cache is very helpful for speeding up access to recently browsed bitmaps, but you can’t limit yourself to images available in memory. A component such as a GridView with a larger data set can easily consume the memory cache. Your application may be interrupted while performing other tasks (such as making phone calls), and tasks in the background may be killed or the cache may be released. Once the user resumes your app, you have to process each image again. In this case, the hard disk cache can be used to store bitmaps and reduce the loading time of images after they are freed by the memory cache. Of course, loading images from hard disk is slower than memory, and should be done in background threads because hard disk reads are unpredictable. Note: If images are accessed very frequently, ContentProvider may be better used to store cached images, such as in an application such as Image Gallery. More about the content of the memory buffer and disk cache in official Google tutorial developer.android.com/develop/ind…

The Android Universal image-loader Image cache is the most widely used Image cache and supports most of the features of the mainstream Image cache. Project address: github.com/nostra13/An… 2. Picasso Square Open Source Image caching project address: github.com/square/pica… Features: (1) automatically detect adapter reuse and cancel the previous download (2) image transform (3) load local resources (4) set placeholder resources (5) support debug mode 3. ImageCache ImageCache, including memory and Sdcard cache item address: Github.com/Trinea/Andr… Features: (1) Support the prefetch of new images, support waiting queue (2) including two level cache, Customize file name saving rules (3) Can choose a variety of cache algorithms (FIFO, LIFO, LRU, MRU, LFU, MFU and other 13) or customize cache algorithms (4) Can easily save and initialize recovered data (5) Support different types of network processing (6) can initialize cache according to system configuration 4. Android network communication framework Volley project address: android.googlesource.com/platform/fr… When we need to communicate with the network in the program, we generally use things like AsyncTaskLoader, HttpURLConnection, AsyncTask, HTTPClient (Apache), etc. Volley was released in Google I/O in 2013. Volley is a network communication library on the Android platform that makes network communication faster, simpler, and more robust. Features: (1) ASYNCHRONOUS download of JSON, images, etc.; (2) Network request scheduling (3) Priority processing of network requests (4) Caching (5) Multi-level cancellation of requests (6) Interworking with an Activity and its lifecycle (cancelling all network requests at the end of the Activity) Adapter

Adapter is widely used in Android, especially in lists. Therefore, an Adapter is a “hub” for data, so memory optimization is necessary. The following is a standard usage template: use convertView and ViewHolder for cache processing

62 @Override 63 public View getView(int position, View convertView, ViewGroup parent) { 64 ViewHolder vHolder = null; 66 if (convertView == null) {67 convertView = inflater.inflate(... , null); 69 vHolder = new ViewHolder(); 70 vHolder.img= (ImageView) convertView.findViewById(...) ; 71 vHolder.tv= (TextView) convertView.findViewById(...) ; Convertview.settag (vHolder); convertView.setTag(vHolder); VHolder = (ViewHolder) convertView.getTag(); // convertView = (ViewHolder) convertView.getTag(); 77} 78 / / to object assignment, modification according to the value of the 79 vHolder. Img. SetImageBitmap (...). ; 80 vHolder.tv.setText(...) ; 81 return convertView; 84 static class ViewHolder {85 TextView TV; 86 ImageView img; 87}Copy the code

Object PooL: The basic idea of object PooL is to save used objects and reuse them when they are needed next time, thus reducing the overhead caused by frequent object creation to some extent. Not all objects are suitable for pooling — there is an overhead associated with maintaining object pools. If you pool objects that are not expensive at the time of generation, the “overhead of maintaining the object pool” may be greater than the “overhead of generating new objects”, resulting in performance degradation. But for objects that are expensive to generate, pooling is an effective strategy to improve performance. Thread pools: The basic idea of a thread pool is again an object pool idea, where a large number of (not dead) threads are allocated in memory, and thread scheduling is handled by the pool manager. When a thread task is created, it is removed from the pool and the thread object is returned to the pool after execution. In this way, the performance cost caused by repeatedly creating thread objects is avoided and system resources are saved. Such as: An application to deal with the network, there are a lot of steps need access to the network, in order not to block the main thread, each step is to create a thread, the thread and network interaction, with a thread pool is simple, the thread pool is an encapsulation of the thread, the thread is more convenient to use, only need to create a thread pool, put these steps like a task in the thread pool, Just call the thread pool’s destruction function when the program is destroyed.

Java provides ExecutorService and Executors classes that you can use to build thread pools. Generally, the following four types can be established:

88 / * * to perform a task at a time of thread pool * / 89 ExecutorService singleTaskExecutor = Executors. NewSingleThreadExecutor (); 90 91 / * * with each thread pool * limit the number of a task / 92 ExecutorService limitedTaskExecutor = Executors. NewFixedThreadPool (3); 93 94 / * * all tasks are one-time start thread pool * / 95 ExecutorService allTaskExecutor = Executors. NewCachedThreadPool (); 96 97 / * * create a task can be performed in the specified time the thread pool, can repeat * / 98 ExecutorService scheduledTaskExecutor = Executors. NewScheduledThreadPool (3);Copy the code

Note: Use caching sparingly, as memory is limited. Can save the path address do not store picture data, not often use as far as possible do not cache, when not empty.