Android development of high-performance (memory optimization)


Here Insert Picture Description
Memory problem: abnormal (OOM memory allocation failure, etc.), Caton
improvements both directions:

Optimization of RAM

That reduced run-time memory. OOM program to prevent the occurrence of an exception, as well as reducing the probability of program because the memory is too large to be killed LMK mechanism.

Optimization ROM

I.e. reduced to the volume of the program ROM. Here it is mainly to reduce the space occupied by the program to prevent due to lack of space leads ROM can not be installed.

The development of mobile devices

Equipment performance rating:
mobile devices have developed a Facebook called device-year-class open source library.

2008 140MB RAM ,2018 Mate 20 Pro 8GB RAM。
Here Insert Picture Description

Myth: Native memory do not control

Native much memory, physical memory is insufficient, lmk began to kill the process.
eg: bitmap manually assigned to the Native heap and released.

// 步骤一:申请一张空的 Native Bitmap
Bitmap nativeBitmap = nativeCreateBitmap(dstWidth, dstHeight, nativeConfig, 22);

// 步骤二:申请一张普通的 Java Bitmap
Bitmap srcBitmap = BitmapFactory.decodeResource(res, id);

// 步骤三:使用 Java Bitmap 将内容绘制到 Native Bitmap 中
mNativeCanvas.setBitmap(nativeBitmap);
mNativeCanvas.drawBitmap(srcBitmap, mSrcRect, mDstRect, mPaint);

// 步骤四:释放 Java Bitmap 内存
srcBitmap.recycle();
srcBitmap = null;

Memory leak detection and modification

Memory leak

A. A memory leak monitoring program

Method One: leakcanry

It lifecycle Activity or investigation by a weak reference object, if found memory leaks automatically dump Hprof file, get the shortest path disclosure by HAHA library, and finally through the notification show.

  • dumphprof still cause the application apparent Caton (SuspendAll Thread).

By leakcanry do simple customization, we can achieve the following closed-loop monitoring a memory leak.
Here Insert Picture Description

Method Two: DDMS

After AndroidStudio 3.0 open DDMS Google can not give up DDMS

  • In the SDK of android-sdk / tools / [path and configuration ADB command is the same path] there monitor.bat batch files;
    Here Insert Picture Description

1, you need to click on the update heap in a debugging process

2, click on the right side of the road using the heap, click on the cause gc, the situation can be viewed in real-time memory

Method three: the command line

adb shell dumpsys meminfo <package_name|pid> [-d]

adb shell ps to find the corresponding pid or package name
Here Insert Picture Description

Method four: Allocation Tracker

  • Fragmentation of information
  • Like with Traceview, automated analysis can not be done, manually start each end.
  • Allocation Tracking time and will not cause too much impact on the performance of the phone itself, but before it is stopped until the data dump, and even regular cell phone stuck ANR.

Method five: android studio Profiler

II. System Memory leaks Hack Fix

AndroidExcludedRefs lists some of the reasons cited examples because the system can not be released, at the same time for most of the examples, will provide recommendations on how to fix recommendations to hack through. ,,, micro letter

Adoption of the fallback recovery of memory

Activity leak causes the Activity reference to the Bitmap, DrawingCache and so can not be released, resulting in pressure on the memory, means for recycling reveal all the details have been leaking Activity, try to recover the resources it holds, only a leak Activity shell, thereby reduce the pressure on memory.

Practice is also very simple, start from rootview view of recursive release all child view images involved in the Activity onDestory time, background, DrawingCache, listeners, etc. resources to become an Activity does not account for the resource shell, it will not leak picture cause resources to be held.

  Drawable d = iv.getDrawable();
  if (d != null) {
      d.setCallback(null);
  }        
  iv.setImageDrawable(null);

Overall, we not only know how some memory leaks solutions can be, more importantly, through routine testing and monitoring, to get memory leak detection and modification of a set of closed-loop system.

Some methods of reducing runtime memory

When we can ensure that the application does not appear in the memory leak, we need some other way to reduce run-time memory. More often, we really only want to reduce the probability of occurrence of the OOM application.

A. Reduce bitmap memory footprint

See the next chapter

II.'S own memory monitor

For the system function onLowMemory and other functions for the entire system, it is, for this process, the difference from its dalvik memory OOM not reflected, nor in time for our callback function to release memory.

  • Real-time monitoring process heap memory usage reaches the set value that is about to inform the relevant memory modules release:
Runtime.getRuntime().maxMemory();  
  Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory()
  • Mode of operation
    on a regular basis (every 3 minutes foreground) to get this value, this value when we reached a dangerous level (eg 80%), we should be primarily to release our various cache resources (bitmap for the bulk of cache).
WindowManagerGlobal.getInstance().startTrimMemory(TRIM_MEMORY_COMPLETE)

III. There are unscrupulous use open process

Each empty process also consumes 10MB.
For webview, library, etc., because there is a memory leak or take up too much system memory problem, we can adopt a separate process. The current micro-channel will put them in a separate process tools.

IV. Detailed reporting OOM

When the crash OOM system occurs, memory information. large heap, inBitmap, SparseArray. . .

GC optimization

GC performance test

For example pause hang time, total time, GC throughput, we can get by sending an ANR log SIGQUIT signal.

adb shell kill -S QUIT PID
adb pull /data/anr/traces.txt

它包含一些 ANR 转储信息以及 GC 的详细性能信息:
sticky concurrent mark sweep paused:	Sum: 5.491ms 99% C.I. 1.464ms-2.133ms Avg: 1.830ms Max: 2.133ms     // GC 暂停时间

Total time spent in GC: 502.251ms     // GC 总耗时
Mean GC size throughput: 92MB/s       // GC 吞吐量
Mean GC object throughput: 1.54702e+06 objects/s 

A. GC type

1.GC_FOR_ALLOC
when heap memory is not enough time likely to be triggered, especially when the new object. Dalvik.vm.heapstartsize values can be increased, so that the number of GC_FOR_ALLOC during startup can be reduced. Note that this trigger is carried out in a synchronized manner.

2.GC_EXPLICIT
the gc can be invoked, such as system.gc, general gc thread's priority is relatively low, so the garbage collection process will not necessarily be immediately triggered.

3.GC_CONCURRENT
when the object size distribution is triggered when more than 384K, note that this is a recycling of an asynchronous manner. If you find a large number of repeated Concurrent GC appears, indicating that the system may have been the object of greater than 384K are allocated, but these are often Some temporary objects are repeatedly triggered. To give us hints are: object reuse is not enough.

4.GC_EXTERNAL_ALLOC (3.0 after the system is spent)

II. Memory jitter

A short time a large number of objects are created and immediately released.
This operation may affect the frame rate, and so that the user perceived performance problems.

Three. GC optimization

1. The string concatenation optimization
reduces string plus sign stitching, to use StringBuilder.
Reduction StringBuilder.enlarge, provided capacity initialization;

logging.println(">>>>> Dispatching to " + msg.target + " " +
                msg.callback + ": " + msg.what);

2. Read files to optimize read files ByteArrayPool, the initial setting capacity, reduce expand.

3. Resource Reuse
global buffer pool, for frequent application, the type of reuse object releases

4. reduce unnecessary or unreasonable objects
example ondraw, getview decrease target application should try to reuse. Something more is logical, for example, continuously circulating application of local variables, etc.

The selection of reasonable data format SparseArray, SparseBooleanArray, and LongSparseArray instead Hashmap

Set a good optimization goals:
for example, equipment for 512MB and 2GB or more for equipment, are two completely different optimization ideas.
For Southeast Asia, Africa, the user, and that the standard memory optimization will become more demanding of some.

3 aspects of memory optimization

Equipment classification, Bitmap memory leaks and optimizing these three aspects.

1, grading equipment

Similar device-year-class, low-end machines closed complex animations, or some function, using 565 format picture, a smaller cache and so on.

if (year >= 2013) {
    // Do advanced animation
} else if (year >= 2010) {
    // Do simple animation
} else {
    // Phone too slow, don't do any animations
}
  • Cache management
    unified cache. When the system memory is low, the timely release of memory.
  • Process model
    an empty process will take up 10MB of memory. Increased process unscrupulous.
  • Installation package size
    volume of code, resources, and so the picture library, taking with them the memory of a great relationship.

2, Bitmap Optimization

Android bitmap evolution analysis:

  • Android 2.x system, when dalvik allocated + maximum external allocated + newly assigned size> = dalvik heap when OOM occurs. Where the bitmap is placed in the external medium.
    Bitmap object on the Java heap, while the pixel data is placed in Native memory. If you do not manually invoke recycle, Bitmap Native memory recovery entirely dependent finalize the callback function, the students are familiar with Java should know that this opportunity is not controllable.
    After Android 2.x system BitmapFactory.Options hidden inside the reflective opening inNativeAlloc, bitmap will not be counted in the application of the external.

  • Android 3.0 ~ Android 7.0 will unify Bitmap object and the pixel data into the Java heap.
    So even if we do not call recycle, Bitmap memory will be recovered along with the object.
    Java heap limit has only to 512MB, perhaps my physical memory as well as 5GB, but because of lack of application or Java heap memory lead to OOM.
    Android 4.x systems, the abolition of external counter, bitmap distribution similar to the change of java dalvik heap in the application, as long as the allocation of new memory allocated +> = dalvik heap maximum time OOM will occur (the statistical rule art and dalvik operating environment or consistent)
    can be used with facebook fresco library resources can be put in the picture native in.

  • android 8.x moved from Java heap the native heap
    there a realization, can put Native Bitmap in memory, you can also do a quick release and objects together, while GC when memory can also be taken into account to prevent abuse? NativeAllocationRegistry can once you meet these three requirements, Android 8.0 is the secondary use of this mechanism back to Native memory.
    Android 8.0 also adds hardware bitmap Hardware Bitmap, it can reduce the picture memory and improve rendering efficiency.

specific method:

1. Uniform Gallery

eg: low-end machines use 565 format. You can use Glide, Fresco or take self-development can be. And the need to further the Bitmap.createBitmap, BitmapFactory associated interface also gather together.

2. Unified Monitoring

In the gallery after the reunification very easy to monitor the use of the Bitmap, there are three things to note here.

  • Big picture monitoring. Prevent wide. Pixel waste
    namely image size should not exceed the size of the view. In this regard, we can override drawable with ImageView.
    Present image pixel waste, rational use of .9 map
  • Duplicates monitoring.
    Replies: The duplicate bitmap analysis is done in the background server, is now directly calculate hash for all bitmap array of methods horses right.
  • Pictures of total memory.
    When OOM crash, can also take up the picture of total memory, Top N picture memory are written to the crash log to help us troubleshoot the problem.

A good process imageLoader, 2.X, 4.X 5.X picture or the user can load hidden, but can also be an adaptive size, quality, etc. placed in the frame.

3, memory leaks

Memory leak is simply not reclaim unused memory.

Memory leak is divided into two types:
the same object leak.
Leak every time a new object, hundreds of thousands of useless objects may occur.

Excellent frame design can reduce or even avoid programmers make mistakes. Many memory leaks are caused by unreasonable design framework, a variety of single cases everywhere, MVC Controller in the life cycle is far greater than View.

  • Java memory leaks
    establish similar LeakCanary automated monitoring program.
    During development, we hope to leak pop-up dialog box appears, allowing developers to more easily identify and solve problems.
  • OOM monitor the
    US mission there is a memory leak Android automated link analysis component Probe, which generates Hprof memory snapshot in the event of OOM, and then do further analysis on this file through a separate process. But use this file for further analysis online. However, using this online tool risk is relatively large, a memory snapshot in time of the crash may cause a secondary collapse, and some mobile phones generate Hprof snapshot might take several minutes to experience the impact of this on users is relatively large.
  • Native memory leak monitoring
    one I talked about Malloc debugging (Malloc Debug) and Malloc hook (Malloc Hook) it seemed fairly stable. In WeMobileDev recent article "Android terminal memory optimization practice micro-letters", the micro letter also did some other program above attempts. https://mp.weixin.qq.com/s/KtGfi5th-4YHOZsEmTOsjg?
    It is not so perfect.

The development process can be used to troubleshoot memory leaks and MAT Androd Profiler tools used in conjunction with, and daily monitoring of the key into the system, so that timely detection of problems.

Memory monitor
some performance monitoring memory leak problem, usually only open to internal staff and very small part of the user.
Online: the need to monitor memory-related problems by other, more effective ways.

Acquisition mode
in accordance with user sampling, rather than pay-per-sample. Users continue to collect hits.
Users at the front desk, you can capture every 5 minutes PSS, Java heap, pictures total memory.

Calculate the index

Memory UV abnormal rate = PSS over 400MB of UV / UV acquired
value by which the PSS can get get Debug.MemoryInfo value by which the PSS Debug.MemoryInfo.
Touch the top rate: Java may reflect the use of memory, if more than 85% of the maximum heap limit, GC will become more frequent, likely to cause OOM and Caton.

内存 UV 触顶率 = Java 堆占用超过最大堆限制的 85% 的 UV / 采集 UV

long javaMax = runtime.maxMemory();
long javaTotal = runtime.totalMemory();
long javaUsed = javaTotal - runtime.freeMemory();
// Java 内存使用超过最大限制的 85%
float proportion = (float) javaUsed / javaMax;

General client only reported data, all calculations are processed in the background, so you can do flexible.

3.GC monitoring
in the laboratory or an internal trial environment, we can also monitor the situation Java memory allocation and GC by Debug.startAllocCounting, to note that this option has some impact on performance, although there can also be used, but has been Android is marked as deprecated. By monitoring information, we can get the number and size of memory allocation, as well as initiate GC number of times.

long allocCount = Debug.getGlobalAllocCount();
long allocSize = Debug.getGlobalAllocSize();
long gcCount = Debug.getGlobalGcInvocationCount();

After the Android 6.0 system can get more precise information about GC.

// 运行的 GC 次数
Debug.getRuntimeStat("art.gc.gc-count");
// GC 使用的总耗时,单位是毫秒
Debug.getRuntimeStat("art.gc.gc-time");
// 阻塞式 GC 的次数
Debug.getRuntimeStat("art.gc.blocking-gc-count");
// 阻塞式 GC 的总耗时
Debug.getRuntimeStat("art.gc.blocking-gc-time");

We need to pay particular attention to the number of GC blocking and time-consuming, because it will suspend application threads may cause the application to occur Caton.

Published 13 original articles · won praise 2 · Views 7383

Guess you like

Origin blog.csdn.net/qq_37165429/article/details/104820032