Android Memory leak Summary (memory Detection tool included)

Source: Internet
Author: User
Tags creative commons attribution

1190000006852540

The main points are three pieces:

    • Static storage: Distributed at compile time, which exists during the entire run of the program. It mainly stores static data and constants.

    • Stack area: When the method executes, local variables inside the method body are created in the stack memory, and the memory is freed automatically after the method finishes.

    • Heap area: A new object is usually stored. Reclaimed by the Java garbage collector.

The difference between stacks and heaps

Stack memory is used to store local variables and function parameters. It is advanced out of the queue, in and out of the one by one correspondence, does not produce debris, the operation of high efficiency and stability. When the scope of the variable is exceeded, the variable is invalidated, and the memory allocated to it is freed and the memory space can be reused.

Heap memory is used to hold object instances. The memory allocated in the heap is automatically managed by the Java garbage collector. Frequent new/delete in heap memory can cause a lot of memory fragmentation, which reduces program efficiency.

For the storage location of non-static variables, we can be rude to think:

    • The local variable is in the stack, where the object entity that the reference variable points to exists in the heap.

    • Member variables are located in the heap. Because they belong to a class, the class is eventually new to the object and stored as a whole in the heap.

Introduction to four reference types

The fundamental principle of the GC releasing an object is that the object is no longer referenced (strongly referenced). So what is a strong reference?

Strong references (strong Reference)

The most common thing we use is a strong quote, as follows:

IPhotos iPhotos = new IPhotos();

The JVM prefers to throw an OOM, and it does not let the GC reclaim objects with strong references. When a strong reference is not used, all references to the object can be explicitly set through obj = null, so that the object can be reclaimed. As for when to recycle, depending on the GC algorithm, here do not delve into.

Soft references (Soft Reference)

SoftReference<String> softReference = new SoftReference<>(str);

If an object has only soft references, the garbage collector does not recycle it if there is enough memory space, and the memory of those objects is reclaimed if there is insufficient memory space. The object can be used as long as it is not reclaimed by the garbage collector.

Soft references have often been used as image caches, but Google Now recommends replacing them with LruCache because LRU is more efficient.

In the past, a popular memory cache implementation is a SoftReference
or WeakReference bitmap cache, however this was not recommended.
Starting from Android 2.3 (API level 9) The garbage collector are more
Aggressive with collecting soft/weak references which makes them
Fairly ineffective. In addition, prior to Android 3.0 (API level 11),
The backing data of a bitmap was stored in native memory which are not
Released in a predictable manner, potentially causing an application
To briefly exceed its memory limits and crash. Original

The general meaning is: because after Android 2.3, the GC will be very frequent, resulting in the release of soft reference frequency is also high, which will reduce its efficiency. And 3.0 ago Bitmap is stored in Native Memory, its release is not controlled by GC, so using soft reference cache Bitmap may cause OOM.

Weak references (Weak Reference)

WeakReference<String> weakReference = new WeakReference<>(str);

The difference from a soft reference is that an object with only a weak reference has a more ephemeral life cycle. Because when a GC is found, an object with only a weak reference is reclaimed, regardless of whether the current memory space is sufficient or not. However, because the garbage collector is a very low-priority thread, it is not necessarily quick to find objects that have only weak references--.

Virtual Reference (Phantomreference)

As the name implies, it is a dummy, unlike several other references, a virtual reference does not determine the life cycle of an object, nor can it obtain an object instance from a virtual reference. Virtual references must be used in conjunction with the reference queue (Referencequeue). When the garbage collector prepares to reclaim an object, if it finds that it has a virtual reference, it will add the virtual reference to the reference queue associated with it before reclaiming the object's memory. A program can know if a virtual reference to the object exists in the reference queue to see if the object is going to be recycled.

Introduction to Android's garbage collection mechanism

The Android system has a generational Heap memory model that performs different GC operations based on the different memory data types in memory.

The model is divided into three zones:

    • Young Generation

      1. Eden

      2. Survivor Space

        1. S0

        2. S1

    • Old Generation

    • Permanent Generation

Young Generation

Most new objects are placed in the Eden area, and when the Eden area fills up, the Minor GC (lightweight GC) is executed, and then the surviving objects are transferred to the Survivor area (with S0,s1 two). Minor GC also examines objects in the Survivor area and transfers them to another Survivor area, so there is always an empty Survivor area.

Old Generation

The Major GC (large GC) is executed after the old Generation area is full after a long-lived object (the object survived after multiple Minor GC).

Before Android 2.2, when the GC was executed, the thread of the app was paused and 2.3 began to add a concurrent garbage collection mechanism.

Permanent Generation

Storage method area. General Storage:

    • Information for the class to load

    • static variables

    • Final constant

    • Properties, method information

fps

Here is a simple introduction to the concept of frame rate to make it easier to understand why a large number of GC is prone to Dayton.

APP Development, the general pursuit of the interface frame rate of up to 60 fps (frames per second), then what is the concept of this FPS?

    • 10-12 FPS, you can feel the effect of animation;

    • FPS, you can feel the smooth and consistent animation effect, the film commonly used frame rate (not the pursuit of FPS is to save costs);

    • FPS, the most fluid effect, for higher fps, the brain has been difficult to detect the difference.

Android sends a VSYNC signal every minute of the day, triggering a rendering of the UI (i.e., one frame per ms), and if the entire process stays within a few milliseconds, it will reach a smooth picture of FPS. More than a few MS will cause the Dayton. So if a large number of GC occurs during UI rendering, or if the GC takes too long, it can cause the drawing process to be more than MS (FPS drops, drop frames, etc.), and our brains are very sensitive to dropped frames, so if memory management is not done, it will bring a very bad experience to the user.

Introduce the concept of memory jitter, which may be used later in this article.

Memory jitter

A large number of new objects within a short period of time, after reaching the threshold value of young Generation, triggers the GC, resulting in the new object being recycled. This behavior affects the frame rate, which results in the Dayton.

Memory jitter probably behaves like this in an Android-provided memory Monitor:

Common memory leaks and solutions in Android

Collection Class Disclosure

If a collection is a global variable (such as a static decoration), and the collection is stored directly in a memory-intensive object (rather than being stored by a weak reference), then as the set size increases, memory consumption will increase, and when the Activity is destroyed, These objects in the collection cannot be reclaimed, causing a memory leak. For example, we prefer to do some caching by static HashMap, which is to be careful, the objects in the collection are recommended to be accessed in a weakly referenced manner, and are considered to be released manually when not needed.

A single case of memory leaks

The static characteristics of a singleton cause its life cycle to be as long as the application.

Sometimes when creating a singleton, if we need a context object, then there is no problem if the application context is passed in. If the activity's context object is passed in, then when the activity life cycle ends, the activity's reference is still in the form of a sample, so it is not recycled, and the singleton life cycle is as long as the application, so this creates a memory leak.

Solution One: In the creation of a singleton structure is not directly used in the context, but through this context to obtain the context of application. The code is as follows:

public class AppManager {    private static AppManager instance;    private Context context;    private AppManager(Context context) {        this.context = context.getApplicationContext();// 使用Application 的context    }    public static AppManager getInstance(Context context) {  if (instance != null) {  instance = new AppManager(context); }  return instance; }}

The second solution: when constructing a singleton, you do not need to pass in the context, write a static method directly in our application method, return to the context through Getapplicationcontext, and then call this static method directly in the singleton to get Context

Memory leaks due to non-static internal classes

In Java, non-static inner classes (including anonymous inner classes, such as Handler, which runnable anonymous inner classes are most likely to cause memory leaks) hold strong references to external class objects (such as Activity), while static inner classes do not reference external class objects.

A non-static inner class or anonymous class can access the resource property member variables of an external class because it holds a reference to the external class, such as a static inner class.

Because an ordinary inner class or anonymous class relies on an external class, you must first create an external class, create a normal inner class, or an anonymous class, and static inner classes can be created in other external classes at any time.

Handler memory leaks can follow my other article specifically for handler memory leaks: Links

Leakage of WebView

There is a big compatibility problem with WebView in Android, and some WebView even have a memory leak. So the usual way to solve this problem is to open another process for WebView, through the aidl and the main process to communicate, WebView the process can be based on the needs of the business to choose the right time to destroy, so as to achieve the full release of memory.

Memory leaks due to Alertdialog

new AlertDialog.Builder(this)        .setPositiveButton("Baguette", new DialogInterface.OnClickListener() {            @Override public void onClick(DialogInterface dialog, int which) { MainActivity.this.makeBread(); } }).show();

Dialoginterface.onclicklistener's anonymous implementation class holds the mainactivity reference;

In the implementation of Alertdialog, the Onclicklistener class will be wrapped in a Message object (depending on the Setbutton method of the Alertcontroller Class), and the message will be copied internally (a As can be seen in the Mbuttonhandler of the Lertcontroller class, only one of the two copies of the message is recycle, and the other (the Message object referenced by the Onclicklistener member variable) will be leaked!

Workaround:

    • Android 5.0 above does not exist for this issue;

    • The disclosure of the message object is unavoidable, but if it is just an empty message object, it will be put into the object pool as a post-use, there is no problem;

    • Let the Dialoginterface.onclicklistener object not hold a strong reference to the outer class, as implemented with the static class;

    • Before the Activity exits dismiss dialog

Memory leaks due to drawable

Android has solved this problem after 4.0. You can skip over here.

When we rotate the screen, the current activity is destroyed by default, and then a new activity is created and the previous state is maintained. During this process, the Android system reloads the program's UI views and resources. Suppose we have a program that uses a large Bitmap image, and we don't want to reload the Bitmap object every time the screen rotates, the simplest way is to use the static modifier for this Bitmap object.

onCreate(Bundle state) {    super.onCreate(state);    TextView label = new TextView(this); label.setText("Leaks are bad"); if (sBackground == null) { sBackground = getDrawable(R.drawable.large_bitmap); } label.setBackgroundDrawable(sBackground); setContentView(label);}

But the above method may cause a memory leak when the screen rotates, because when a drawable is bound to a view, the View object is actually a callback member variable of the drawable, and the static sbackground in the example above holds A reference to the TextView object, while TextView holds a reference to the Activity. When the screen rotates, Activity cannot be destroyed, which creates a memory leak problem.

This problem mainly occurs before 4.0, because the implementation of the Setcallback method in 2.3.7 and the following versions drawable is directly assigned, and from the 4.0.1, Setcallback uses weak reference to handle the problem, avoiding memory leaks.

Memory leaks due to resource not shutting down

    • Broadcastreceiver,contentobserver or something like that didn't cancel the registration

    • Cursor,stream and the like don't have close

    • An infinite loop of animations does not stop until the Activity exits

    • Some other of the release's not release, the Recycle no recycle ... Wait a minute.

Summarize

It's easy to see that most of the problems are caused by static!

    • Be careful when using static, and focus on the references that the static variable holds. Use weak references as necessary to hold some references

    • It is also important to note that when using non-static inner classes, they hold references to external classes. (use RxJava's classmate in subscribe also should notice unsubscribe)

    • Note Releasing resources at the end of the life cycle

    • When using property animations, stop (especially looping animations) when not in use, otherwise a memory leak will occur (Activity cannot be released) (View animation will not)

Introduction to several memory detection tools
    • Memory Monitor

    • Allocation Tracker

    • Heap Viewer

    • Leakcanary

Memory Monitor

Located in Android Monitor, the tool can:

    • Easy display of memory usage and GC status

    • Whether the fast positioning of the stutter is related to GC

    • Fast positioning of the Crash is related to high memory consumption

    • Quickly locate potential memory leaks (memory footprint is growing)

    • But we can't pinpoint the problem.

Allocation Tracker

The tool uses:

    • You can locate information such as Object type, size, time, thread, stack, and so on, assigned in your code

    • Can locate memory jitter issues

    • Locating memory leaks with the Heap Viewer (you can find out where the compromised objects were created, etc.)

How to use: in Memory Monitor there is a start Allocation Tracking button to start tracking after clicking Stop Tracking will display the statistics results.

Heap Viewer

This tool is used to:

    • displaying memory snapshot information

    • Collect information once per GC

    • Find a tool for memory leaks

How to use: in Memory Monitor there is a Dump Java Heap button, click on it, in the upper left corner of the statistics report select by the package category. With the initiate GC (execute GC) button of memory Monitor, you can detect leaks such as memories.

Leakcanary

Important things to say three times:

        for (int i = 0; i < 3; i++) {            Log.e(TAG, "检测内存泄露的神器!"); }

Leakcanary specific use no longer repeat, self Google.

    • Published on September 08, 2016
    • Sina Micro-Blog
    • Twitter
    • Facebook
Articles you may be interested in
    • Memory issues-Collections-nuggets 137 views
    • Positioning, analysis and resolution strategies for memory leaks in Android applications 6 favorites, 682 views
    • Mobile App test Android performance Test 120 views

This work is licensed under the Creative Commons Attribution-NonCommercial use-Share 4.0 International license agreement in the same way. 1 Reviews Echo • September 12, 2016

About here: Here's a simple introduction to the concept of frame rate to make it easier to understand why a large number of GC is prone to Dayton.

I also have a description of the GC in this article, which says

All the garbage collections is ' Stop the world ' events because all application threads is stopped until the Operation Co Mpletes.

Since Young generation keeps short-lived objects, Minor GC was very fast and the application doesn ' t get affected by this.

However Major GC takes longer time because it checks all the live objects. Major GC should be minimized because it would make your application unresponsive for the garbage collection duration. So if you have a responsive application and there is a lot of Major garbage Collection happening, you'll notice timeout Errors.

Because the GC stops all thread events, Major GC consumes events for a long time, so it can cause application unresponsive, which better explains the relationship between memory and rendering.

Please advise ^_^

Android Memory leak Summary (memory Detection tool included)

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.