In Android
the system, garbage collection is automatic and relatively hidden, which leads to some memory problems that are not obvious, and it is difficult to locate problems after they occur. Common memory problems include memory leaks, memory overflow ( Out of Memory
), memory jitter, etc.
The main reasons we do memory optimization are as follows:
- To reduce
OOM
the rate, the most common memory problem is thatOOM
the requested memory may not be releasedOOM
; - To reduce the freeze,
Android
there are many reasons for the freeze in the system, among which is the freeze caused by the memory . The reason why the memory problem will affect the fluency of the interface is because of the garbage collection mechanism. When it is runningGC
, all threads must stop working, including the main thread. Therefore, whenGC
the operation of drawing the interface is triggered at the same time, the drawing task will be put on hold, resulting in frame drop, that is, the interface freezes; - To increase the survival time of the application,
Android
the system will clean up the process according to a specific process, and give priority to cleaning the background process. If an application is running in the background and occupies a lot of memory, it will be cleaned up first. If we wantAPP
to survive longer, unused memory should be cleaned up as soon as possible;
As for which objects need to be recycled? Using the search algorithm/reachability algorithm, select some objects as objects GC Roots
, and search downward. The path that the search passes is called a reference chain. When an object is GC Roots
not connected to the application chain, it indicates that the object needs to be recycled. The following objects are available as GC Roots
:
- Objects referenced in native method stacks;
- Objects referenced in the virtual machine stack;
- Objects referenced by global static variables;
- Objects referenced by global constants;
Java Virtual Machine (4) - Objects in the Java Virtual Machine
1 memory leak
A memory leak means that our application no longer needs some objects, but some references to the objects are still not released, resulting in no way for these objects to be recycled. From the perspective of memory, it means that a piece of memory is no longer used, but there is no way to recycle it, resulting in waste of memory. For example, an anonymous inner class holds a reference to an outer class, so that the outer class cannot be recycled, and a memory leak will occur.
Memory leaks will lead to more and more memory that cannot be reclaimed, and less and less available memory, until the application has no more available memory applications, or even serious cases OOM
.
2 out of memory ( OOM Out Of Memory
)
Memory leaks generally cause the application to freeze, and in extreme cases OOM
, OOM
the reason is that the memory threshold is exceeded. There are two main reasons:
- Memory leaks, resulting in failure to release in time
OOM
; - Some logic consumes a lot of memory, which cannot be released in time or exceeds the cause
OOM
;
Most of the things that can consume a lot of memory are because of image loading. This is OOM
where it occurs most frequently. Image loading, one is to control the number of loading each time, and the other is to ensure that it does not load every time you slide, and loads after sliding. In general, first-in-last-out is used instead of first-in-first-out. But generally we use fresco
or Glide
wait for open source libraries for image loading.
The following are two situations that lead to memory overflow:
View memory consumption through the command line ( adb shell dumpsys meminfo 包名 -d
):
For image memory optimization:
- Image zooming, for example, the width and height of a picture is
200 x 200
, butView
the width and height are100 x 100
, at this time, the image needs to be zoomed, throughinSampleSize
realization; - To reduce the memory occupied by each pixel, in
API 29
, it willBitmap
be divided into six levels:ALPHA_8
,RGB_565
,ARGB_4444
,RGBA_F16
, :HARDWARE
ALPHA_8
: Do not store color information, each pixel occupies1
a byte;RGB_565
: Only storeRGB
channels, each pixel occupies2
a byte,Bitmap
there is no high requirement for color, you can use this mode;ARGB_4444
: deprecated, useARGB_8888
instead;ARGB_8888
: Each pixel takes up4
bytes to maintain high-quality color fidelity, and this mode is used by default;RGBA_F16
: Each pixel occupies8
a byte, suitable for wide color gamut andHDR
;HARDWARE
: A special configuration that reduces memory usage and speeds upBitmap
drawing;
- The bytes occupied by each pixel of each level are different, and the stored color values are also different. The
100
picture of the same pixelARGB_8888
occupies400
bytesRGB_565
only when it occupies200
bytes. Therefore, in some scenarios, modifying the image format can also achieve the effect of reducing the memory by half.
Memory multiplexing to avoid repeated allocation of memory.Bitmap
The memory occupied is relatively large. If it is created and recycled frequentlyBitmap
, it is easy to cause memory jitter, so the memory should be reused as much as possibleBitmap
. AtAndroid 3.0(API 级别 11)
the beginning, the system introducedBitmapFactory.Options.inBitmap
the field. If this option is set,Options
the decoding method using the object willBitmap
attempt to reuse when generating the targetinBitmap
, which meansinBitmap
that memory for is reused, improving performance while removing memory allocations and deallocations. However,inBitmap
there are certain restrictions on the way of using.Android 4.4(API 级别 19)
Before the system only supported the multiplexing of bitmaps of the same size, after 4.4, as long asinBitmap
the size of isBitmap
larger than the target - Partial loading strategy for large images: There is another situation for image loading, that is, a single image is very large and compression is not allowed. For example, display: world map, Qingming Shanghe map, Weibo long map, etc. First of all, if it is not compressed and loaded according to the original image size, then the screen must not be large enough, and considering the memory situation, it is impossible to load the entire image into the memory at one time. Therefore, the optimization idea in this case is generally partial loading, which is
BitmapRegionDecoder
achieved by
The memory optimization strategies mentioned above Bitmap
are actually relatively simple, and we may rarely use them in development,
because our commonly used image frameworks Glide
have already encapsulated these, so in general, we do not load images. These special operations are required.
3 memory thrashing
Objects that are created or destroyed frequently in a short period of time GC
are easy to trigger and cause memory jitter, such as for
creating temporary object instances in a loop.
Because GC
all the threads will stop working at that time, which leads to lag. To avoid memory thrashing, the following actions should be avoided:
- Try to avoid creating objects in the loop body;
View.onDraw()
Try not to create objects in custom methods, because this method will be called frequently;- For objects that can be reused, consider using an object pool to cache them;
reference
Android memory optimization in-depth analysis
about android performance optimization - memory articles
Android performance optimization - memory optimization