Android Memory leakage and android Memory leakage

Source: Internet
Author: User

Android Memory leakage and android Memory leakage

Android Memory leakage is a common problem. program memory leakage can easily cause OOM. Therefore, we need to know how to find out memory leaks and avoid memory leaks. First, we need to know some basic knowledge.

Four Java references

Strong reference: a strong reference is the most common reference in Java. If you create an object at will and reference it elsewhere, it means a strong reference. The strongly referenced object Java would rather not reclaim OOM.

Soft reference: soft reference is a weak reference than a strong reference. During Java gc, if the soft reference object is recycled, if the first gc fails, the soft-referenced objects will be recycled. Soft-referenced objects are suitable for cache processing and can be used together with the reference Queue (ReferenceQueue, when an object is recycled, its soft reference is saved in the reference queue.

Weak references: weak references are weaker references than soft references. When Java executes gc, if the objects referenced by the weak references are recycled, no matter whether it is used or not, it will recycle objects with weak references. However, gc is a low-priority thread and will not recycle your objects in time. It can be used with the reference queue. when an object is recycled and its weak reference is saved, it will be placed in the reference queue.

Virtual Reference: The Virtual Reference is the same as that without a reference. It must be used with the reference queue. When Java recycles an object, if it finds that it has a virtual reference, the Virtual Reference is added to the reference queue associated with the object before it is recycled.This feature allows you to take measures before an object is recycled.

The following is an example:

Public class Main {public static void main (String [] args) throws InterruptedException {ReferenceQueue <Object> referenceQueue = new ReferenceQueue <> (); String sw = "Virtual Reference "; switch (sw) {case "soft reference": Object objSoft = new Object (); SoftReference <Object> softReference = new SoftReference <> (objSoft, referenceQueue); System. out. println ("obtained before GC:" + softReference. get (); objSoft = null; System. gc (); Thread. sleep (1, 1000); System. out. println ("Get after GC:" + softReference. get (); System. out. println ("result in queue:" + referenceQueue. poll (); break;/** get before GC: java. lang. object @ 61bbe9ba * after GC: java. lang. result In the Object @ 61bbe9ba * queue: null **/case "weak reference": Object objWeak = new Object (); WeakReference <Object> weakReference = new WeakReference <> (objWeak, referenceQueue); System. out. println ("obtained before GC:" + weakReference. get (); objWeak = null; System. gc (); Thread. sleep (1, 1000); System. out. println ("Get after GC:" + weakReference. get (); System. out. println ("result in queue:" + referenceQueue. poll ();/** get before GC: java. lang. object @ 61bbe9ba * after GC get: null * result in the queue: java. lang. ref. weakReference @ 610455d6 **/break; case "": Object objPhan = new Object (); PhantomReference <Object> phantomReference = new PhantomReference <> (objPhan, referenceQueue); System. out. println ("obtained before GC:" + phantomReference. get (); objPhan = null; System. gc (); // the difference here is that virtual references will be added to the ReferenceQueue queue before the memory of objPhan is recycled by gc, and other references will be used when the reference is gc, references will be added to the ReferenceQueue Thread. sleep (1, 1000); System. out. println ("Get after GC:" + phantomReference. get (); System. out. println ("result in queue:" + referenceQueue. poll ();/** get before GC: java. lang. object @ 61bbe9ba * after GC get: null * result in the queue: java. lang. ref. weakReference @ 610455d6 **/break ;}}}
Java GC

Currently, the virtual machines of oracle jdk and open jdk are both Hotspot, while those of android are Dalvik and Art.

GC algorithm: reference count

In short, the reference count is used to calculate the number of each object's reference. If the reference is + 1, the reference is-1 if it is not referenced, and the object with the reference count of 0 is recycled. To achieve garbage collection

Disadvantages: if both objects should be recycled but they are dependent on each other, the reference of both objects will never be 0, and they will never be recycled,Unable to solve the problem of circular reference

This algorithm is used only in a few virtual machines.

Modern GC Algorithms

  • Mark and Sweep GC): Starting from the "GC Roots" set, the memory is traversed once, And all objects that can be directly or indirectly referenced by GC Roots are retained. The remaining objects are treated as garbage and recycled, this algorithm needs to interrupt the execution of other components in the process and may generate memory fragments.
  • Copying): Divides the existing memory space into two fast ones. Only one of them is used at a time. When garbage collection is performed, the surviving objects in the memory being used are copied to the unused memory block. Then, clear all objects in the memory block in use, switch the roles in two memories, and recycle the garbage.
  • Mark-Compact): First, you need to mark all reachable objects from the root node. However, it does not simply clean up unlabeled objects, but compresses all surviving objects to one end of the memory. Then, all spaces outside the boundary are cleared. This method not only avoids the generation of fragments, but does not require two identical memory spaces. Therefore, the cost-effectiveness is relatively high.
  • Generation Division: Place all new objects in a memory area called the young generation. The young generation features that the objects will be quickly recycled. Therefore, the young generation selects a highly efficient replication algorithm. When an object remains alive after several recycles, the object will be put into the memory space called the old generation. The new generation applies to Replication Algorithms, while the old generation adopts the tag-compression algorithm.

The above four algorithms are referenced by the QQ space team to share Android GC & version = 11000003 & pass_ticket = nhSGhYD4LC9FWvUPv26Y7AdIzqEDu8FTImf2AKlyrCk % 3D.

Causes of Memory leakage

The object is reachable in GC Root, that is, its reference is not empty, so GC cannot recycle it, which will cause memory leakage.

GC Root start point

  • Objects referenced in the Virtual Machine Stack
  • Objects referenced by class static attributes in the Method Area
  • Objects referenced by constants in the method Area
  • Object referenced by JNI
GC can be continued for one second

When an object loses S # x53BB; in the reference chain, does it really want to say goodbye to the world? Actually, it is not. A virtual opportunity will give him a "probation ", each object has a finalize () method. Whether the Virtual Machine suspends the object depends on whether the method of the object is executed, if the method of this object is not covered or the method has been executed once, it will be "executed. It's really "continued for one second"

If the finalize () method of this object should be executed, put it in the F-Queue as a virtual opportunity, A virtual opportunity will automatically create a Finalizer thread later to execute this method for the objects in this queue. If the object successfully saves itself in finalize (), for example, if you strongly reference yourself and an existing object, it will not be recycled. Otherwise, it will be recycled.

However, the virtual machine does not guarantee that the Finalizer thread is executed and then recycled, because if an infinite loop or super time-consuming operation is executed in the finalize () method of an object, if the virtual machine waits for the execution to end, the entire Gc will crash.

First, note that this method can only be executed once. The second time it will mark that this method has been executed and will not be executed again. Second, this method may not necessarily be executed, therefore, do not rely on finalize () for self-help. This is not a good practice.

Concurrent GC and non-concurrent GC

Later, Android2.3 supports concurrent GC.

  • Non-concurrent GC: The VM stops the world when executing GC, that is, it suspends all other threads, usually lasting for hundreds of milliseconds, one Mark, and then directly cleans it.

  • Concurrent GC: Compared with non-concurrent simple gc, generally non-concurrent GC takes hundreds of ms, while concurrent gc takes about 10 ms, greatly improving the efficiency (data comes from: small black house technology), but the concurrent gc requires more CPU resources because it needs to process the modified objects repeatedly.

Differences between the two:

First, non-concurrent GC is simple and crude, and all threads are directly suspended. At this time, there will certainly be no addition or modification in the Java heap. At this time, go to the recursion GC tree and then Mark-clean. However, this will cause a lot of overhead, and everyone is waiting for you. Isn't it a shame? =

However, non-concurrent GC comes from 1.1 points, so there won't be a long wait for synchronization with the thread, but you need to understand the truth, if you want to clean the ground, no one must step on it during this time, so he must have a thread suspension process.

So how is concurrency implemented? First, there are two methods for Jvm to allocate memory.

  • Pointer collision: When a pointer is applied for a piece of memory, the pointer moves the corresponding distance without generating memory fragments, which requires the memory to be quite regular.
  • Idle list: each time you apply for a piece of memory for the desired object, there is a list of the locations that have been applied for, and this location will not be applied for the next application, this applies to scenarios where the memory is not very regular.

Creating objects is a frequent operation. How can we ensure atomicity? Two solutions

  • CAS (Compare and Swap) policy with retry failure to ensure atomicity
  • Each thread allocates a TLAB: Very simple. Each thread has its own memory, so you can lock its own partition when allocating it, improving efficiency.

We use the second 233

So when we get the Java heap lock, the point is that we lock TLAB one by one, instead of locking all at once. Of course, this improves the efficiency of concurrent GC, so it is faster. However, the problem is concurrency, so the next step is to repeat and modify the objects to be modified during one exploration. More CPU resources are required.

Why do we need to focus on GC?

First, we know how to perform GC on the virtual machine so that we can understand how to properly Recycle an object so as not to leak memory.

Second, both concurrent GC and non-concurrent GC will cause the suspension of all other threads, which will cause program freezing.

ART achieves more fine-grained control on GC and smoother GC.

Common Memory leakage case: Handler Memory leakage

First of all, a non-static internal class and Anonymous class will implicitly hold external class references.

Public class MainActivity extends AppCompatActivity {private Handler mHandler = new Handler () {@ Override public void handleMessage (Message msg) {Log. d ("smallSohoSolo", "Hello Handler") ;};@ Override protected void onCreate (Bundle savedInstanceState) {super. onCreate (savedInstanceState); mHandler. postDelayed (new Runnable () {@ Override public void run () {Log. d ("smallSohoSolo", "Running") ;}, 1000*60*10); // execute finish () 10 minutes later ();}}

This code has obvious Memory leakage. First, both Handler and Runnable are anonymous internal class instances, and they both hold MainActivity references,

Some people may say what will happen if the memory leaks for a short time? This is an incorrect idea, because as long as Memory leakage occurs, you only need to perform large memory operations (such as loading a photo wall) during this period ), there is a risk that OOM is caused by this memory leak (the memory is definitely less occupied)

How can I modify the above?

Change Runnable and Handler to static or use them within the external definition.

Other common memory leaks
  • Static variable Memory leakage: When a static variable is used to reference a thing, the reference will always leak if it is not used.
  • Memory leakage caused by singleton: If the used Singleton saves objects that should not be held all the time, the memory leakage will occur.
  • Memory leakage caused by improper use of third-party libraries: for example, when EventBus and Activity are destroyed, the reference is always held and cannot be recycled.
  • There are many more... They are all caused by reference not being cleared.
How to view memory leakage

Simple and crude-> LeakCanary: Library produced by Square. This will occur when Memory leakage occurs.

Budget calculation-> Android Studio Memory tool: you can Dump the current memory path and analyze which objects are in the current state. Strong

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.