Android Optimization Performance Optimization Case (3) jitter and memory leaks

Foreword

This series of articles:
1, by way of explanation easy to understand, explain the practical value of a technology
2, a detailed written source tracking, source capture, structure drawing class, try to explain the principles of the discovery process in detail
. 3, Github can run the Demo project, but I have provided the code, provide more ideas, better ideas, please cv as appropriate
precautions during operation 4, finishing a set of principles in the process of exploring some pit, or in the demo
5, with gif FIG, most intuitive operating results show demo

If you think the details are too thin, you can skip to see the conclusion.
Limited capacity, should the description found inappropriate, welcome messages criticism.

This article connected to one; APP Caton optimization


Body outline

  • jvm memory management knowledge
  • Detecting and processing the jitter memory
  • And a processing memory leak detection

text

jvm memory management knowledge

  • LMK (LowMemoryKill) mechanism
    android bottom will be when the system ran out of memory, according to certain rules to kill some processes to meet the memory needs of other processes. Which consume memory which is an indicator of the level, so the app's memory footprint optimization, can effectively reduce the probability of being killed app system.
  • GC STW mechanism
    GC, garbage collection process, GC threads when performing a task, there will be a STW (stop the world) mechanism, he will put all the other threads are suspended. If the GC calls very frequently, it will lead to the main thread is not smooth, giving the user the feeling is 卡顿.
  • Memory jitter frequent cause OOM
    memory jitter too often, frequently resulting in a large number of objects created and destroyed, can not produce large amounts of contiguous memory space, at this time if there is a need to apply large object memory, it is possible to apply fail, leading OOM内存溢出.
  • Memory leak word to explain
    the object lifecycle hold the life cycle of a strong reference to the object, the discovery life cycle when objects need to be recovered 不能to be recycled, regarded as leakage
  • Reachability analysis GC recovery
  • GC thread can determine whether an object is recovered, according to reachability analysis algorithm to calculate GcRoot, from GcRootthe search down, the GcRootentire object is not directly related to garbage collection.
  • Strong weak references virtual four
    strong and imaginary without saying. The most common strong, there is no special treatment are strong references (including anonymous inner class will hold a strong reference to the outer class). Phantom reference no use, will not be discussed.
    Soft references, as well as to define some use, but does not have an object, use SoftRefrence<T>modified, in memory tense, after GC was collected using a SoftRefrence<T>modified target system if there is enough memory available, the association would not have a soft reference Be recycled. If insufficient, the soft recovery of the associated object reference.
    Weak references ( WeakRefrence<T>), weaker than the soft reference number, as long as the GC trigger object associated with weak references will be recovered.
    注意,使用软和弱引用,要判定关联对象是否为空。

Detecting and processing the jitter memory

We use s development, we usually run the app, usually point RunApp, but there is another choice, that is, after profileApp, app up and running, you will see the window below as profile

After clicking, as will appear below profile, the figure will show network, memory and cpu usage

If the memory of FIG jitter very clear, like ECG such as:

It shows that there is a very clear memory of jitter in urgent need of treatment:

After clicking the graphics area of ​​memory, you can see detailed changes in memory, and memory allocation:

Here is a pit :

If you look from the drawing to smooth the trend memory, and does not appear on the full simulation of jitter figure so exaggerated, there is no memory jitter is not it? It is not. Because our gc, in the case of memory will be unavailable to reclaim memory, if the app take up memory has been relatively small, did not touch the critical value gc, then it will not appear 断崖式下跌. So this was observed not shake the memory, How to do it?

Solution
on Android phones 8.0 or less, there will be a Record button in the lower position (if it is 8.0 or more, you can directly drag and drop to the interception of a memory record):

Click on it, after a while, and then tap: you can find a form below:

This form represents, you Record objects created within this period of time, click the second column Allocations, the number of created sort, find out to create the highest number of objects:

Then, after clicking ranked first String, you will see on the right:

Then click on one of them, you will see a new window:

So far, to find 创建对象the 元凶order this as a clue, find your own classes and methods package name, determine our own code unreasonably create the object.

Later on, under their respective codes do business optimization, and a purpose in mind: Do not let the code for doing the extra things . If we call the api system led to the creation unreasonably large number of objects, then we must consider why this is so the system API to create objects, there is no other way to avoid it, from the business layer of code to the rational use of this api, it is not then consider another system or custom api api.

We did a optimization after, and then run a profile app, and then repeat the process. And so on, until the memory shake achieve the desired state.

to sum up

Optimize memory jitter, the core is to prevent the frequent create objects. Common negative example is: cycle create an object, the object api to create a large number of calls. The main means of optimized, is the object reuse, common means is: object pooling, such as the Message Handler single list pool, Glide's bitmap pools.


And a processing memory leak detection

Classic case : Handling handlermemory leaks caused by the asynchronous task methods

  • Remove all of the tasks in the Activity onDestroy
    @Override
    protected void onDestroy() {
        super.onDestroy();
        handler.removeCallbacksAndMessages(null);//移除所有任务
    }

  • Manner using static inner classes + Activity weak references
    MyHandler handler = new MyHandler(this);
    private static class MyHandler extends Handler {
        WeakReference<Activity> activityWeakReference;

        MyHandler(Activity activity) {
            activityWeakReference = new WeakReference<>(activity);
        }

        @Override
        public void handleMessage(Message msg) {
            //在执行任务的时候,判断弱引用所关联的对象是否为空,能在对象已经被回收的情况下,不去执行不必要的任务
            switch (msg.what) {
              case 1:
                if (activityWeakReference.get() != null) {
                    //TODO
                }
            }
        }
    }

The use of tools

Still profileApp, first profileseen changes in memory.

  • Q: How to determine the memory leaks?
    A: A memory leak is fine effort, can not totally observed, only by virtue of changes in memory profile to speculate .
    For example, after opening the app memory soared, until the maximum memory that can be used outside the app, app crashes ,, this is the most obvious.
    As another example, you repeatedly open and close one interface, find a memory of a stable line ( 内存稳定之后,内存占用值) with each of the opening and closing, are improving, which shows that there is a leak on this interface, the object can not be recovered.

The previous section using profile the most is learned to create objects and reclaim what caused the memory jitter, however, involves leaks, only through profile yet 不能know 哪个类持有了希望被回收的对象的强引用.
Here is necessary to use an additional tool, and his name is called  Eclipse Mat (own Baidu)

To return to the first profile,

Tap, then tap, the interface will automatically jump:

Click on the Save button to save the file locally;

then:

But the file can not be opened directly on the mat.

To locate the SDK directory hprof-conv.exe:

Use cmd command, convert the file, the command is: hprof-conv [源文件名] [目标文件名]
as  hprof-conv 1.hprof 2.hprof a carriage return

The resulting 2.hprofuse of open tools just downloaded Mat:

There are many indicators, but check for memory leaks, we just need to focus on the Histogram button:

This figure will list all the objects you dump the memory of this period, including the framework layer, including our own code creates objects.

Case simulation

I simulated a classic case, which is the previously mentioned Handlerdelay task leads Activitycan not be released, the core code is as follows:

I use a very common way to create an handlerobject and use it to perform tasks a delay, but the delay time of the delay task is Integermaximum, that is, long after the task will be executed. After that, I repeatedly out of this one Activity, and then follow the above way dumpfor a while  hprof, after  hprof-conv the conversion, then Matopen:
The results are as follows:

I filled filter information: SecondActivity Enter:

In our final exit SecondActivityafter, the memory still retains 18a useless object.

It is not that we are 18 leak it?

Not necessarily.

Previously mentioned, only unreasonable strong references, will lead to memory leaks, so we have to exclude weak phantom reference in accordance with the above method.
Then we can see the following interface, the information can be expanded to give all unfold:

Learn Handler源码comrades should look to see to understand, handlercause a memory leak, because there are unreasonably strong references chain,
the above figure can be seen, ultimately callback object holds the  SecondActivityobject.

callback The delay time of the task is too long, has not yet been performed, so strong references will not give you freed while callbackholding the Activityled Activitycan not be released.

How to optimize memory leak

We have just seen the irrational use Handler causes a memory leak, so if you onDestroyremove all of the tasks:

Perform the same tasks, dump down hprof the mat:

After triggering the GC, SecondActivitythe number becomes 0, memory leaks resolved.

Of course, there is another approach, static inner classes + weak.

ps: static inner classes is to prevent internal class holds references to external class, a weak reference to when GC is triggered, the recovery of lost objects WeakRefrence.

public class SecondActivity extends AppCompatActivity {
    Handler handler = new Handler();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_second);
        handler.postDelayed(runnable, Integer.MAX_VALUE);//依然是那个延时很久的任务
    }

    Runnable runnable = new MyRunnable(this);

    private static class MyRunnable implements Runnable {// 静态内部类
        WeakReference<Activity> activityWeakReference;//弱引用

        MyRunnable(Activity activity) {
            activityWeakReference = new WeakReference<>(activity);
        }

        @Override
        public void run() {

        }
    }
}

But then ruled out, a no.

Tips

The above steps, while feasible, but if there are many pages need to troubleshoot the leak, then we go a point to open a page closed, the whole process will be very long uncomfortable. In fact, there is a solution.

Back before the histogram:

Use is: if you want an operation, a hprof before and after each dump operation you named before and after, and then converted with hprof-conv about, and become before_ after_, open both files at the same time with the eclipse mat, then switch to the after_.hprof, click on the image above button:

It will let you choose the file you want to compare, click before_, then filtered SecondActivity:

This embodiment may leak prior to processing, the code region may leak prior to investigation. Simplify our optimization work.

Epilogue

Memory leaks and optimizing the jitter Jvm involves a lot of knowledge, in addition to the points I listed earlier, there are a lot of minutiae. To do memory optimization, JVM needs a solid knowledge base.

Previous: APP Caton optimization

 

Published 56 original articles · won praise 1 · views 2918

Guess you like

Origin blog.csdn.net/chuhe1989/article/details/104478266