Memory-related issues the probability of being asked in an interview is still relatively large, and memory optimization is critical to the performance of a program, so let's learn now!
No nonsense, go straight to the dry goods ~
One, memory leaks
The memory leak is that we did not release the use of a memory space when it was completed.
Main reason: the main reason for a memory leak is that some of the objects that are being held by the object hold references to other objects that should be recycled, causing the garbage collector to not be able to reclaim those objects.
The scene that appears:
1. The cursor of the database is not closed;
2. When constructing adapter, the cache Contentview is not used, and the
3.Bitmap object uses recycle () to free memory when not in use;
4. The life cycle of an object in the activity is greater than the activity;
Two, memory overflow
Memory Overflow Popular understanding is the memory that the software (application) needs to run, exceeds the maximum memory available to it.
The scene that appears:
1, use a large bitmap picture;
Third, memory optimization method:
1, should try to avoid the static member variable reference resource consuming too many instances, such as context. The context tries to use application context as much as possible because the application context has a longer life cycle, and it does not issue a memory leak. Use WeakReference instead of strong references;
2, threads are also an important source of memory leaks. The main reason for a thread's memory leak is that the thread life cycle is not controllable. Change the thread inner class to static inner class;
3, bitmap problem: it can be said that most of the outofmemory problems are due to bitmap problems. Because bitmap occupies a lot of memory, it is a "super fat", especially the resolution of large pictures, if you want to display more than the problem is more significant;
How to solve the memory problem that bitmap brings to us?
1) Timely destruction, although the system can confirm that the bitmap allocated memory will eventually be destroyed, but because it consumes too much memory, it is likely to exceed the Java heap limit. Therefore, in the use of bitmap, should be timely recycle off. Recycle is not sure that the bitmap will be released immediately, but will give the virtual machine a hint: "The picture can be released."
2) Set a certain sample rate, sometimes we want to show the area is very small, there is no need to load the entire picture, and only need to record a reduced image, this time can set a certain sampling rate, then you can greatly reduce the memory occupied. As in the following code:
Bitmapfactory.options Options = new Bitmapfactory.options (); Options.insamplesize = 2;//Picture width is the original One-second, that is, the picture is the original One-fourth
3) Use the LRUCache cache.
4, clever use of soft reference (softrefrence), sometimes we do not retain a reference to it after using bitmap, so we cannot call the Recycle function. At this time, the clever use of soft reference, can make the bitmap in the memory is not fast enough to get effective release;
5, try to use 9path pictures, adapter to use Convertview reuse and so on;
6. The target of resource consumption is closed in time, such as cursor, various sensors, Service and so on;
7, the use of intentservice instead of service, the most important feature of this service is that when the background task execution end will automatically stop, to a great extent, to avoid the possibility of service memory leak;
8. Using Proguard, it has the function of compressing and optimizing code in addition to confusing the code. Proguard will retrieve our code, remove some useless code, and will name the class, field, method, etc., renamed classes, fields and method names will be much shorter than the original, so that the memory has become less occupied;
Optimization Scenarios for ListView:
1>, multiplexing Contentview: is the custom adapter in the GetView method to consider whether the method passed in the parameter contentview is NULL, if NULL to create a contentview and return, if not NULL is directly used In this method, create as few view as possible;
2>, asynchronous load Picture: to Contentview set tag (Settag ()), pass in a Viewholder object, the next time you can directly call Gettag () display the data in the cache, you can achieve the effect of asynchronous loading of image data;
3>: The picture is not displayed when a quick slide list is
When a quick slide list (scroll_state_fling), the picture in item gets the view that needs to consume resources, can not be displayed, but in the other two states: Idle (scroll_state_idle) and vulgar drag (scroll_state_ Touch_scroll), the view is displayed.
If the ListView needs to display a lot of item, consider paging load. For example, to show a total of 100 or more times, we can consider loading 20 first, and so on when the user pulls to the bottom of the list, then to load the next 20.
4> If you have a picture in your custom item, you need to process the picture (reduce the memory of the image);
1. Edge compression of the image 2. Use the option class to save the image size 3. Avoid real-time zooming of pictures, preferably zoom to view size beforehand
5> To avoid using threads in the ListView adapter, threads are the primary cause of memory leaks because the thread's life cycle is not controllable;
We use specific code to see how to avoid Oom
Case one:
Handler Mhandler = new Handler () { @Override public void Handlemessage (Message msg) { Mimageview.setimagebitmap (Mbitmap); }}
In an activity where there is a handler inner class, the handler object implicitly holds a reference to the activity, and handler typically accompanies a time-consuming background thread (such as a network download image) that, after the task has been executed, Notify handler via the message mechanism, and then handler update the image to the interface. However, if the user shuts down the activity during a network request, normally the activity is no longer being used, it is possible that it will be reclaimed during GC checking, but since the thread has not finished executing, and the thread holds the handler reference, This handler also holds the activity reference, which causes the activity to not be recycled (that is, memory leaks) until the network request is over.
There are two ways to solve this problem:
Method One: Through the program logic to protect.
1). Stop your background thread while the activity is closed. When the thread is stopped, it is equivalent to cutting off the handler and externally connected lines, and the activity will naturally be recycled at the right time.
2). If your handler is a message with delay that holds a reference (called postdelayed, then use Handler's Removecallbacks () or removecallbacksandmessages ( Null) method to remove the message object from the message queue.
Method Two: Declare the handler as a static class and add a weak reference to the activity.
Static classes do not hold objects from external classes, so your activity can be recycled. The code is as follows:
Static class MyHandler extends Handler { weakreference<activity > mactivityreference; MyHandler (activity activity) { mactivityreference= new weakreference<activity> (activity); } @Override public void Handlemessage (Message msg) { final activity activity = Mactivityreference.get (); ImageView imageview= (ImageView) Activity.findviewbyid (R.id.imageview); if (activity! = null) { mimageview.setimagebitmap (mbitmap);}}}
Case two,
New Thread (New Runnable () { @Override public void Run () { systemclock.sleep (10000); } }). Start ();
An anonymous inner class is declared in the activity, and if the activity is not completed before the task is destroyed, the memory resource of the activity cannot be reclaimed, causing a memory leak.
The workaround is to use the static inner class and close the thread in a timely manner, as follows:
private static class MyThread extends Thread { private Boolean mrunning = false; @Override public Void Run () { mrunning = true; while (mrunning) { systemclock.sleep ()} } public void Close () { mrunning = false; } }
The call Mthread.close (), which we can display in the OnDestroy () method when the activity exits, ends the thread so that it avoids the memory leak of the thread while avoiding the activity oom.
Each non-static inner class instance holds a reference to an external class, and if the reference is an activity reference, the activity will not be reclaimed when it is destroyed. If your static inner class needs a reference to a related activity to ensure that the functionality works, then you need to make sure that you are using a weak reference to the activity in the object.
So it seems that static is an important weapon to solve the oom problem, that is not every internal class use static to modify it, it is not, only when this class is used in many places in the world to do so, because the static declaration variable life cycle is actually the same as the life cycle of the app, Somewhat similar to application. If a large number of uses, it will occupy the memory space is not released, a few will also cause the memory of the constant overhead, until hung out. Static is generally used to modify basic data types or lightweight objects, to avoid the adornment of collections or large objects, commonly used to decorate global configuration items, tool class methods, internal classes.
Finally, one more extended reading ...
The object that GC recycles?
If the GC discovers that one or a group of objects is unreachable, it reclaims the object from memory. That is, an object is not pointed to by any reference, and the object is recycled when it is discovered by the GC, and if a set of objects contains only references to each other, and no references from outside them (for example, two objects A and B hold references to each other, but no external objects hold references to a or b), This is still not reachable and will be recycled by GC.
What is WeakReference? How do I solve an oom problem?
WeakReference a weak reference, as opposed to a strong reference (which we often refer to), is characterized by the fact that the GC ignores weak references when it recycles, that is, even if a weak reference points to an object, as long as the object is not pointed to by a strong reference (and most often requires no soft reference). The object is reclaimed when it is checked by the GC. If you are concerned about the memory overhead of the app, you can consider using WeakReference, when GC reclamation swept through this area of memory will be recycled, if not so concerned, you can use SoftReference, it will be automatically released in case of insufficient memory request, It can also solve the oom problem. Android since 3.0 also launched the LRUCache class, using the LRU algorithm to free memory, the same can solve oom, if you want to be compatible with the version below 3.0, you need to import v4 package.
Android face question and Answer (ii)