Study on debugging Android Native C++ memory leaks

Study on debugging Android Native C++ memory leaks

[[433799]]

This article is reprinted from the WeChat public account "Program Cat Adult", the author is Program Cat Adult. Please contact Program Cat Adult's public account to reprint this article.

I recently debugged the memory leak problem in the Android Native layer and sorted out some notes to share with you.

Contents of this article

  • How to view memory information?
  • Introduction to Android key memory items
  • How to debug memory leaks
  • Other Tools
  • Review
  • Related information recommended

How to view memory information?

Print in the code, start a thread, and print out the current memory information at fixed intervals [There are many APIs for obtaining memory information, only one method is listed here, which is proven to be effective]

  1. private void startMemProfiler() {
  2. new Thread(new Runnable() {
  3. @Override
  4. public void run() {
  5. while ( true ) {
  6. displayMemory();
  7. try {
  8. Thread.sleep(2000);
  9. } catch (InterruptedException e) {
  10. e.printStackTrace();
  11. }
  12. }
  13. }
  14. }).start();
  15. }
  16.  
  17. private void displayMemory() {
  18. final ActivityManager activityManager = (ActivityManager) getSystemService(ACTIVITY_SERVICE);
  19. ActivityManager.MemoryInfo info = new ActivityManager.MemoryInfo();
  20. activityManager.getMemoryInfo(info);
  21. Log.i(TAG, "System remaining memory:" + (info.availMem / (1024 * 1024)) + "M" );
  22. Log.i(TAG, "Is the system running in low memory: " + info.lowMemory);
  23. Log.i(TAG, "When the system's remaining memory is lower than " + (info.threshold / (1024 * 1024)) + "M" + ", it is considered low memory operation" );
  24. Log.i(TAG, "Native memory allocated by the system: " + (Debug.getNativeHeapAllocatedSize() / (1024 * 1024)) + "M" );
  25. Log.i(TAG, "Native memory remaining in the system: " + (Debug.getNativeHeapFreeSize() / (1024 * 1024)) + "M" );
  26. Log.i(TAG, "System's total native memory size: " + (Debug.getNativeHeapSize() / (1024 * 1024)) + "M" );
  27. }
  • Using the adb command line
  1. adb shell dumpsys meminfo /
  2. adb shell dumpsys meminfo tv.danmaku.bili

The information displayed by dumpsys meminfo is shown in the figure:

Introduction to Android key memory items

Here we only introduce the fields we need to focus on:

  • Dalvik Heap: The memory occupied by the virtual machine, which can be understood as the memory occupied by the Java layer.
  • Native Heap: The heap memory occupied by the Native layer, which can be understood as the memory occupied by the C/C++ side. [Items we need to focus on]
  • Private Dirty/Clean: Memory that is private to the process. After the process is destroyed, this part of memory can be recycled [Dirty/Clean: Whether the page has been modified. If it has been modified, it is dirty. When the page is eliminated, it will be swapped out. ]
  • VSS (Virtual Set Size): Indicates the size of the total memory address space accessible to a process. This size includes the memory space that the process has requested but not yet used. In practice, this method is rarely used to indicate the memory usage of a process, and it is inaccurate to use it to indicate the memory usage of a single process. [Not shown in the figure, but this thing exists in Linux]
  • RSS (Resident Set Size): Indicates the actual address space used by a process in RAM, including the memory occupied by all shared libraries. This is also inaccurate to indicate the memory occupied by a process. [Not shown in the figure, but this thing exists in Linux]
  • PSS (Proportional Set Size): Indicates the actual address space used by a process in RAM, which includes the memory occupied by shared libraries in proportion. If there are 3 processes using the same shared library, then the PSS of each process includes 1/3 of the shared library memory. This method is more accurate in representing the memory usage of the process, but when only one process uses the shared library, the situation is exactly the same as RSS. [One advantage of PSS measurement is that the PSS of all processes can be added together to determine the actual memory occupied by all processes. This means that PSS is an ideal way to measure the actual RAM usage of a process and its RAM usage relative to other processes and the total available RAM. ]
  • USS (Unique Set Size): Indicates the size of the memory space occupied by a process itself, without including any other components. This is the best way to indicate the size of the process memory! [Not shown in the figure, but this thing exists in Linux] [So: VSS>=RSS>=PSS>=USS]
  • Graphics: The memory used by the graphics buffer queue to display pixels to the screen (including GL surfaces, GL textures, etc.). (Note that this is memory shared with the CPU, not GPU-specific memory.) [The official document says so, but I don’t understand what it means, https://developer.android.com/studio/profile/memory-profiler]
  • If you want to know more about other fields, you can refer to the official documentation: https://developer.android.com/studio/command-line/dumpsys

How to debug memory leaks

  • By using the method of elimination + printing the current memory information (introduced above), comment out any suspected leaks to see if there are any more leaks [rough].
  • The code layer globally covers malloc and free. The essence is to record each malloc node and store it in a linked list. When freeing, the node is removed from the linked list. If there are still nodes in the linked list at the end, it means there is a memory leak. [It is easy to use in most scenarios, but it can only detect C language code in the current code memory, and cannot detect leaks in other libraries]
  • Overload operator new and operator delete. The principle is similar to the above. [Only memory operated by new and delete in C++ can be detected, but memory operated by malloc and free cannot be detected]
  • Use Android Studio Profiler tool: Android 10 or above is required. For details, please refer to: https://developer.android.com/studio/profile/memory-profiler. [Overall, it feels not very easy to use]
  • Integrate tencent/matrix on the Demo side, and you can choose to hook the malloc and free symbols under a dynamic link library. If a memory leak is found in a dynamic library, the leak stack information will be printed. [Recommended]

Use of matrix

By integrating the matrix library, you can choose to hook the malloc and free symbols of a dynamic link library, and then work in a similar way to libctools, storing malloc nodes, deleting the nodes when freeing, and finally counting memory leaks.

The integration method of matrix can be found in the github library: https://github.com/Tencent/matrix

The principle of hook can be seen at: https://github.com/iqiyi/xHook/blob/master/docs/overview/android_plt_hook_overview.zh-CN.md

If a memory leak occurs, there will be files with json and log suffixes, as shown in the figure:

The json file will count which library leaked how much memory, and the log file will record the specific leaked stack information.

After getting the specific leaked stack information, you can use the addr2line tool to locate the specific code:

  1. /Users/xxx/Android/ndk/21.4.7075529/toolchains/llvm/prebuilt/darwin-x86_64/bin/aarch64-linux-android-addr2line -C -f -e /Users/xxx/project/java/build/intermediates/stripped_native_libs/debug/ out /lib/arm64-v8a/libBMMCapture-Android.so 83a70

The effect is as shown below:

Other Tools

dumpsys has some other functions, which are used as follows:

  • memory adb shell dumpsys meminfo
  • CPU adb shell dumpsys cpuinfo
  • framerate adb shell dumpsys gfxinfo
  • adb shell dumpsys display
  • poweradb shell dumpsys power
  • Battery status adb shell dumpsys batterystats
  • batteryadb shell dumpsys battery
  • alarm adb shell dumpsys alarm
  • Locationadb shell dumpsys location

Replay shooting memory leak investigation

Background: Whenever a memory leak occurs, it is often suspected that it is caused by an update to a module or other library, but there is no evidence and no suitable methodology for troubleshooting memory leaks.

Analysis and solution:

  • When connecting to each third-party library, write a demo to perform effect tests, memory tests, and performance tests. Run the demo every time you update the third-party library. Or every time a problem occurs, run the demo to see if it is caused by this library.
  • When integrating a third-party library, reduce code coupling to ensure that a third-party library can be flexibly removed. Consider using conditional compilation and other methods to facilitate problem troubleshooting.
  • Introduce tool troubleshooting:

○Memory leak: Android uses matrix, iOS uses Xcode

○ CPU usage: Android profiler, iOS Xcode

○ GPU occupancy rate: Android Qualcomm uses snapdragonprofiler, or perfdog (charged)

Related information recommended

https://developer.android.com/topic/performance/memory-management?hl=zh-cn

https://developer.android.com/studio/profile/memory-profiler

https://developer.android.com/studio/command-line/dumpsys

https://github.com/iqiyi/xHook/blob/master/docs/overview/android_plt_hook_overview.zh-CN.md

References

https://developer.android.com/studio/command-line/dumpsys

https://blog.csdn.net/pugongying1988/article/details/16838859

https://www.jianshu.com/p/8203457a11cc

<<:  WeChat adds new feature: Fans can file complaints against those who pursue celebrities without any bottom line

>>:  Only 12 days after updating iOS 15.1: Battery health dropped from 92% to 87%, iPhone XR suffered negative optimization

Recommend

How to establish long-term relationship chains with users?

This article will explore the tricks to attract u...

Tips and strategies for becoming a “super user”!

The free feast on the Internet is becoming a thin...

Are probiotics, which can be bought everywhere, really good for health?

Reviewer: Wu Xinsheng Deputy Chief Physician, Dep...

Product promotion: How to advertise?

A very important part of advertising is the selec...

Meteor hammers, maces...how many other tricks can a dinosaur's tail have?

Dinosaurs are definitely the stars of ancient cre...

Baidu Mini Program data, how to view traffic data of Baidu Smart Mini Program?

Smart Mini Program developers can use the data in...

In a mobile Internet company, what are the KPIs of each department?

KPI, or key performance indicator, is a performan...