Memory Leaks and Memory Overflows in Android

1. Memory leak

1. The phenomenon and essence of memory leaks

Memory leak ( Memory Leak) refers to the phenomenon that some objects are no longer used, but cannot be reclaimed by the garbage collector, and still occupy the memory space, which leads to the leak of this piece of memory.

The reason why the garbage collector cannot reclaim some objects is because these objects are still being referenced. Therefore, the essence of memory leaks is that objects with a short life cycle are referenced by objects with a long life cycle, resulting in objects with a short life cycle not being reclaimed by the garbage collector in time.

2. The hazards of memory leaks:

A small amount of memory leaks will not have a big impact. When the leaked memory becomes larger and the available free memory becomes smaller and smaller, GC (garbage collection mechanism) will be triggered more easily, and other threads will be stopped when GC is in progress. work, so it may cause the interface to freeze and so on;

With the accumulation of memory leaks, the accumulation of a large number of memory leaks may cause memory overflow.

3. Memory leaks involved in Android

In Android applications, memory leaks should pay attention to the following aspects

(1) Reduce the use of static: the life cycle of the member variable modified by the static keyword is equal to the life cycle of the application. If it is used in large quantities, it will occupy the memory space and will not be released. If it accumulates, it will cause continuous memory overhead. ; And you should avoid static member variables referencing instances that consume too much resources (such as Context). If you need to refer to Context, use Applicaiton's Context.

(2) Avoid non-static inner classes (anonymous inner classes) holding external class references: non-static inner classes (anonymous inner classes) will hold references to outer classes by default, while static inner classes will not. The memory leak of Handler, AsyncTask (the bottom layer of AsyncTask is Handler), multi-threaded (implementing the Runnable interface, inheriting the Thread class) belongs to this kind of memory leak. In this case, the method of static inner class + weak reference should be used.

(3) De-registration in time after registration: BroadcastReceiver, Service, ContentObserver, EventBus, etc. must be de-registered in the corresponding life cycle method after registration.

(4) The resource object is closed in time after use : Cursor during database operation , IO stream when reading and writing files  and other objects are not closed;

(5) When the Bitmap object is not in use, call recycle() to release memory: Bitmap consumes a lot of memory, and using more Bitmaps may exceed the limit of the Java heap at once. Therefore, when the Bitmap is used up , it must be recycled in time . recycle cannot immediately release the memory of the Bitmap , but will recycle the bitmap at the next working time of the garbage collector.

(6) Non-Application Context is not referenced in the singleton mode : due to the static nature of the singleton, its life cycle is as long as the life cycle of the application, so if the Context of the Activity is not properly referenced, it will cause memory leaks, so The Context in the singleton mode must refer to the Application's Context.

4. Memory leak analysis tools:

(1) Static code analysis tool lint: It can be used to detect some codes that may cause memory leaks. Usually, when programming, pay attention to the various yellow warnings prompted by lint.

(1) Android Profiler that comes with Android Studio: The Android Profiler in Android Studio 3.0 and later replaces the Android Monitor tool.

(2) Open source leakcanary:.

Two, memory overflow

Memory overflow ( Out Of Memoery: OOM ) means that the memory used by the application application exceeds the maximum value specified by the system. The Android system has a maximum limit on the memory that each application can use. When the memory application exceeds this threshold, OOM Crash will occur. 

1. Memory overflow in Android

(1) Pay attention to item reuse of ListView:

The ListView used in the early days needs to reuse items manually. Otherwise, a large number of ItemViews will be generated when sliding quickly, and the garbage collector will not have time to reclaim memory, and OOM may occur (this is also the main reason why ListView is replaced by RecyclerView);

(2) Pay attention to the loading of pictures:

a . When loading multiple pictures: For loading multiple pictures, we generally use a three-level cache (memory cache, local cache, network cache) to load the pictures. Using the cache can make the next loading faster, so keeping a certain amount of image cache in memory will help the next time the image is displayed faster. But too many bitmap objects cannot be stored in the memory, so the LRUCache algorithm is generally used to save the pictures in the memory, and the number is controlled within a certain amount.

b. Loading a large long picture: If a picture is very, very large, then the program may OOM as soon as it is loaded, and the application crashes before using the third-level cache. Therefore, special processing is required for the display of large pictures : although the picture is very large, the controls that need to be displayed for this picture may be very small. We can get the width and height of the picture first, and then get the width and height of the control that this picture needs to display, and then we can get the zoom ratio of the picture and the control. Finally, the sampling rate of the picture is set according to the zoom ratio, so as to reduce the memory usage of a single picture.
    BitmapFactory.Options options = new BitmapFactory.Options();
    //只得到图片的大小,不去加载图片的内容
    options.inJustDecodeBounds = true;
    Bitmap boundBitmap = BitmapFactory.decodeFile(filePath,options);
    int imageWidth = boundBitmap.getWidth();
    int imageHeight = boundBitmap.getHeight();
    //计算 inSampleSize 的值 此时可以根据控件大小和图片大小来得到缩放比例 这里先写成 2
    options.inSampleSize = 2;//图片宽高都为原来的二分之一,即图片为原来的四分之一
    options.inJustDecodeBounds = false;
    Bitmap bitmap = BitmapFactory.decodeFile(filePath,options);

Guess you like

Origin blog.csdn.net/beita08/article/details/127717728