The neglected memory Leaks for Android performance optimization

Source: Internet
Author: User

Cause

Blogging is like telling a story, having a cause, passing, result, character, place, and time. Let me tell you a story today. People, it must be me. The story takes place in the last two days, at the location of the company where coder June works. I stumbled upon a strange phenomenon that day, and as I opened the page of our app, Memory monitor showed more and more RAM (the previous page had already been completed). Hey? What the heck?

After

Have a problem to solve it, as the saying goes, there are bugs to be on, no bug to write a bug. What exactly is the problem that causes this phenomenon?

The memory-related issues in Android are just a few things:

    • Memory Leak Leaks
    • Memory Churn Ram Jitter
    • OutOfMemory Memory Overflow

Assi, think about how it's so much like a memory leak. Is that the end of it? Let's analyze it at 1.1.

Memory-related data

About memory we might want to know about three points:

  • Total Memory

      private String gettotalmemory () {String str1 = "/proc/meminfo";//system memory information file    String str2;    String[] arrayofstring;    Long initial_memory = 0;        try {filereader localfilereader = new FileReader (STR1);        BufferedReader localbufferedreader = new BufferedReader (Localfilereader, 8192);        STR2 = Localbufferedreader.readline ();//Read Meminfo first line, total system memory Size arrayofstring = Str2.split ("\\s+");        for (String num:arrayofstring) {log.i (str2, num + "\ t"); } initial_memory = Integer.valueof (Arrayofstring[1]). Intvalue () * 1024;//gets the total system memory, in kilobytes, multiplied by 1024 to byte localb    Ufferedreader.close (); } catch (IOException e) {} return Formatter.formatfilesize (Getbasecontext (), initial_memory);//byte converted to KB or MB, memory size gauge Rasterize}  
  • System currently available memory

    private String getAvailMemory() {    // 获取android当前可用内存大小    ActivityManager am = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);    ActivityManager.MemoryInfo mi = new ActivityManager.MemoryInfo();    am.getMemoryInfo(mi);    //mi.availMem; 当前系统的可用内存    return Formatter.formatFileSize(getBaseContext(), mi.availMem);// 将获取的内存大小规格化}
  • The memory we can use

    Each Android device will have a different total ram size and free space, so different devices offer different sizes of heap limits for apps. You can get the available heap size for your app by calling Getmemoryclass ()). If your app tries to request more memory, a outofmemory error will occur.

    In some special scenarios, you can declare a larger heap space by adding largeheap=true properties under the Application tab of manifest. If you do this, you can get to a larger heap size by Getlargememoryclass ()).

    However, the ability to get a larger heap is designed for a small number of applications that consume a lot of RAM (such as an editing application for a large picture). Don't be so easy because you need to use a lot of memory to request a large heap size. Use the large heap only when you know exactly where to use a lot of memory and why the memory must be preserved. Therefore, use as little as possible the large heap. Using additional memory affects the overall user experience of the system and makes the GC run longer each time. The performance of the system becomes compromised when the task is switched.

    In addition, the large heap does not necessarily get a larger heap. On some severely restricted machines, the size of the large heap is the same as the usual heap size. So even if you apply for the large heap, you should check the actual heap size by executing getmemoryclass ().

    private String getAllocationMemory() {    // 获取系统分配的内存大小    ActivityManager am = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);    //开启了android:largeHeap="true",米4系统能分配的内存为512M,不开启为128M    //return  am.getLargeMemoryClass()+"";    //return  am.getMemoryClass()+"";}       
Four types of references in Java

Before starting the analysis, it is necessary to understand the memory allocation and recycling of Java.

Java's data types fall into two categories: basic data types, reference data types.

The value of the base data type is stored in the stack memory, and the reference data type requires two storage space, one in the heap memory, for storing the object of that type, and the other in the stack memory to store a reference to the object in the heap memory.

Where the reference type variable is divided into four categories:

    • Strong references

      The most common form of reference. To assign an object to a reference type variable, it is a strong reference.

      As long as a reference is a strong reference, the garbage collector will never be able to reclaim the object's memory space unless the JVM terminates.

    • Soft references

      When the memory resource is sufficient, the garbage collector does not reclaim the memory space of the object that the soft reference corresponds to, but when the memory resource is tight, the object of the soft reference is reclaimed by the garbage collector.

      //创建一个Student类型的软引用SoftReference<Student> sr = new SoftReference<Student>(new Student());
    • Weak references

      The object of the weak reference is freed, regardless of whether the JVM's memory resources are tense or not, as long as the garbage collector is running.

    • Virtual reference

      A virtual reference is equal to no reference, and its corresponding object cannot be accessed through a virtual reference.

      Soft and weak references are added to the reference queue after their objects are reclaimed, and virtual references are added to the reference queue before their objects are reclaimed. So a virtual reference can do something before its object is freed.

      Virtual Reference and Reference queue binding methods:

      //创建引用队列  ReferenceQueue<String> queue = new ReferenceQueue<String>();  //创建虚引用,并绑定引用队列  PhantomReference<String> str = new PhantomReference<String>("啦啦啦",queue);   
Garbage Collection for garbage collection in Android

The Android system triggers GC operations at the right time, and once the GC is in place, some objects that are no longer used are recycled .

When performing GC operations, any action on all threads will need to be paused, and other actions will continue to run after the GC operation is completed.

In general, a single GC does not take up too much time, but a large number of non-stop GC operations can significantly occupy the frame interval (16ms). If there are too many GC operations in the frame interval, then natural other similar calculations, rendering operations such as the availability of time has become less

Memory leak leaks

A memory leak represents an object that is no longer being used because it is incorrectly referenced and cannot be reclaimed. A memory leak causes the remaining available heap size in the memory generation to be smaller, which can lead to frequent triggering of GC and further performance issues.

It's really simple to summarize: there are invalid references!

Memory leaks can cause a lot of problems, and a common memory leak causes the following problems:

    • application lag, slow response time (high memory consumption, JVM virtual opportunity to trigger GC frequently);

    • The application is being emptied from the background process;

    • Application of inexplicable crashes (i.e. exceeding the heepsize threshold caused by oom);

Memory Leak analysis Tool

Seeing these problems, I suddenly found that it was almost 0.0 closer to the truth.

To get a clearer picture of the current application's memory usage in real time, we need some tools to implement it. There are two types of tools that are more useful:

    • Memory Analyzer Tool
    • Leakcanary

Below we introduce separately.

Memory Analyzer Tool

Memory analysis Tools (point I download) is a tool that specializes in analyzing the Java heap Data reference, and we can use it to conveniently locate the cause of memory leaks, and the core task is to find the GC root location. Next, use the steps.

Fetching Memory information

It is convenient to grab memory information in Andriodstudio, there are two ways:

    • Using Android Device Monitor

      Click Tool–>android Device Monitor on the Android Studio toolbar

      In the Android Device monitor screen, select the package name of the application you want to analyze, click the update heap to refresh the statistics, then click Cause GC to view the current heap usage, click Dump HPROF file, Save the current memory information of the app as a hprof file, put it on the desktop, and operate as

    • Direct access

      The latest version of Android Studio can get the Hprof file directly, but note that you must manually click the Initiate GC button to manually trigger the GC before use, so that the captured memory usage does not include the unreachable object.

      Wait a moment, the generated file will appear in the captures, then select the file, right-click to convert to the standard hprof file, you can open in the mat.

Viewing analysis using the Mat tool

Here I wrote a simple demo to test, this demo has a total of two pages, after jumping to the second page, the new open a ready to print activity information.

/** * 打印ActivityName */public void printActivityName() {    for (int i = 0; i < 100; i++) {        new Thread(new Runnable() {            @Override            public void run() {                while (true)                    try {                        Thread.sleep(1000 * 30);                        Log.e(ActivityHelper.class.getSimpleName(), ((Activity) mContext).getClass().getSimpleName());                    } catch (InterruptedException e) {                        e.printStackTrace();                    }            }        }).start();    }}   

Multiple entry into the secondactivity will find that the memory has been growing and has not decreased.

And log will not stop the output log, print the current activity's name.

After you open the crawled file in the mat

There are a lot of features in the mat, so we just have to learn a few of the most common ones. The most central pie chart shows the ratio of the largest number of objects to the amount of memory that is provided in this graph, and we can ignore it. There are two very useful tools in the red box that we often use.

Histogram can list the name, number, and size of each object in memory.

Dominator Tree sorts all in-memory objects by size, and we can parse the reference structure between objects.

Let's see histogram first.

What should we do to analyze memory leaks? That is, an object that analyzes large memory. But if we have the target object, the upper left corner supports the regular expression, we enter secondactivity. Here we see that we have 5 instances of secondactivity, because we quoted secondactivity that are not destroyed, resulting in many instances.

Next to the secondactivity right-click List objects, with incoming references see the specific secondactivity instance, as shown in:

If you want to see the specific cause of a memory leak, you can right-click the Path to GC Roots-exclude weak references for any one of the mainactivity instances, as shown in the following:

You can see the red box because our thread holds an instance of secondactivity, all causing a memory leak.

In addition, we can choose to view the package structure of our project in the form of

Next we look at the Dominator Tree.

About Dominator Tree We need to pay attention to three points:

    • First the retained heap represents the total memory of this object and other references it holds (both direct and indirect), so the first two rows of the retained heap are the largest, and when we analyze memory leaks, the largest memory object is also the most suspect.
    • The object with the yellow dot means that it can be accessed by GC roots, and the object that can be accessed by GC Root cannot be recycled, according to the above explanation.
    • Not all objects with yellow dots are leaking objects, and some object systems need to be used all the time and should not be recycled. We can note that some of the objects with the yellow dots will write a system Class on the far right, stating that this is a managed object, not an object created by ourselves and causing a memory leak.

Now we can right what we want to see. Right-click Path to GC Roots-exclude weak references, why choose Exclude weak references? Because a weak reference does not prevent the object from being reclaimed by the garbage collector, we will simply exclude it from this, and then analyze it step in and out.

Leakcanary

Leakcanary is an open source project, a memory leak detection tool, is the famous GitHub open source organization Square contribution, its main advantage lies in the premature detection of memory leaks, configuration simple, crawl intimate, the disadvantage is that there are still some bugs, However, normal use of 90% is OK, and its core principle is similar to the Mat tool.

Because the configuration is very simple, there is not much to say, official documents.

Let's look at the results of the analysis

Simple and straightforward!

Common memory leak scenarios
    • When constructing adapter, no cached Convertview is used

    • Bitmap object does not call recycle () to free memory when it is in use

    • Improper use of context causes memory leaks: Do not maintain a long life cycle reference to an activity context. Try to replace everything in a place where you can use the application ApplicationContext instead of the context.

    • Static instances of non-static inner classes are prone to memory leaks: In a class, if you cannot control the life cycle of its inner classes (for example, some special handler in activity, etc.), use static classes and weak references as much as possible (for example, Viewroot implementations).

    • Beware of memory leaks caused by threads not terminating, such as associating a thread with a life cycle over activity in activity, and remembering to end the thread when exiting the activity. A typical example is that the Handlerthread run method is a dead loop, it does not end itself, the thread's life cycle exceeds the activity life cycle, and we must manually thread.getlooper () in the destruction method of the activity. Quit (); no leaks.

    • There is no memory leak caused by the registration and anti-registration of the object, such as registering a broadcast receiver, registering an observer (typically, for example, a database listener), etc.

    • Create and close the leak caused by no paired occurrence; For example, the cursor resource must be manually shut down, WebView must be manually destroyed, and objects such as streams must be manually closed.

    • Instead of creating objects (such as Onmeasure) in a high-frequency method or loop, you can use Hashtable to create a set of object containers that take those objects from the container without having to release each new one.

    • Avoid memory leaks caused by errors in code design patterns, such as circular references, a holding b,b holding c,c holding a, such designs who are not released.

Results

There's only one truth, and that's exactly what happened to me because of a memory leak. Programmers, who do not tread a hole, jump out, pat on the body of dust, summed up, after two days is a help coder. Source

The neglected memory Leaks for Android performance optimization

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.