The neglected memory Leaks for Android performance optimization

Source: Internet
Author: User

Cause

Blogging is like telling a story. To have a cause, pass, result, character. Location and time. Let me tell you a story today.

People. It must be me.

The story takes place in the recent 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

Solve the problem, as the saying goes. There are bugs to be on. There is 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 it. Think carefully about how this is like a memory leak. Is that really 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 apply for a lot of other memory, there will be outofmemory errors.

    In some special scenarios, you can declare a larger heap space by adding the properties of the largeheap=true to the manifest application tag. Assuming 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 a large image editing application). Don't be so easy because you need to use a lot of memory to request a large heap size.

    Just use the large heap 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 take longer to execute 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 still check the actual heap size obtained 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 beginning 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. Piece in the heap memory. The object used to store the type, and a piece in the stack memory. A reference to store the object in heap memory.

The reference type variables are divided into four categories:

    • Strong references

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

      Only if 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 corresponding object, but when the memory resource is tight, the corresponding 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 strained or if the garbage collector executes it only.

    • Virtual reference

      A virtual reference is equal to no reference and cannot be visited by a virtual reference to its corresponding object.

      Soft references and weak references after their objects are recycled. These references are added to the reference queue, 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, all threads need to be paused for whatever operation. After the GC operation is complete, other operations are sufficient to continue.

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). Assuming that there are too many GC operations in the frame interval, then natural other similar calculations. Less time is available for rendering and other operations

Memory leak leaks

A memory leak indicates that an object that is no longer being used cannot be reclaimed because it is incorrectly referenced. 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.

In fact, it's very easy to sum up: there are invalid references!

Memory leaks can cause a lot of problems. Common memory leaks cause problems such as the following:

    • application Lag. Slow response Time (JVM virtual opportunity frequently triggers GC when memory is high);

    • 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

See these problems. Suddenly found that it seems to be closer to the truth 0.0.

To get a clearer picture of the current application's memory usage in real time, we need to implement it through some tools. 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 still very convenient to grab the memory information in Andriodstudio, there are two methods:

    • 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 app's current memory information to a hprof file, and put it on the desktop. Operations such as the

    • Direct access

      The latest version of Android Studio can get the Hprof file directly, but be sure to manually trigger the GC manually by clicking Initiate Gcbutton before use. In this case, the memory usage is not included in the Unreachable object.

      Wait a moment, the generated file will appear in the captures now. Then select File and right-click to convert to standard hprof file. Can be opened in the mat.

Viewing analysis using the Mat tool

Here I wrote a simple demo to test, this demo a co-owned 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

The mat offers a lot of functionality, and here we just have to learn a few of the most frequently used ones. The most central pie chart shows the ratio of the largest number of objects to the amount of memory, which is not available in this picture. 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 are able to parse the reference structure between objects.

Let's see histogram first.

What should we do to analyze memory leaks?

An object that parses large memory.

But if we have the target object, the upper left-hand corner supports the normal form, we enter secondactivity. Here we see. We have 5 instances of secondactivity. As we quoted secondactivity the ready-made is not destroyed. Cause there will be very many instances.

Next to the secondactivity right-click List objects, with incoming references see the detailed secondactivity instance. For example, as seen in:

Assuming that you want to see the details of the memory leak, you can mainactivity a random instance of the right-click Path to GC Roots, exclude weak references, as shown in the following example:

Can see the red box because our thread holds an instance of secondactivity. All cause a memory leak.

In addition We are able to 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 retained heap of the first two rows is the largest. When we analyze memory leaks, the largest memory object is also the most suspect.
    • Objects with a yellow dot indicate that they can be visited by GC roots, and according to the above explanations, objects that can be visited by GC root cannot be recycled.
    • Not all objects with yellow dots are leaking objects, and some object systems need to be used all the time. Should not have been recycled. We can notice. Some of the objects with the yellow dots will write a system Class on the far right, stating that this is an object that is managed by systems and not created by ourselves and causes 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. So we're just taking it out of here. Then step by step analysis.

Leakcanary

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

Because the configuration is very simple. There's 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 cache is used for Convertview

    • 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 the context wherever you can use the application ApplicationContext.

    • Static instances of non-static inner classes Easy causes memory leaks: A class that assumes that you cannot control the life cycle of internal classes within it (such as some special handler in activity). Use static classes and weak references as much as possible (for example, Viewroot implementations).

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

    • There is no memory leak caused by the registration of the object and the counter. For example, the registration of radio receivers, register observers (typically such as database monitoring) and so on.

    • Create and close without a pair of leaks; For example, the cursor resource must be closed manually and WebView must be destroyed manually. Objects such as streams must be closed manually, and so on.

    • Do not create objects (such as Onmeasure) in a very high-frequency method or loop, and you can use Hashtable to create a set of object containers to fetch those objects from the container. Instead of every new and released.

    • Avoid memory leaks caused by errors in code design patterns, such as circular references, a holds B. b holds c. C holds a, and this design is not released.

Results

The truth is only one, that is, it is because of a memory leak that I encountered the situation. Program Ape, who has not stepped on a hole, jump out, pat on the body of dust. Summing up, two days is a good coder. Source

The neglected memory Leaks for Android performance optimization

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.