Recently, I was debugging the Memory leak problem in Android Native layer. I sorted out some notes and shared them with you
This article directory
- How do I view memory information?
- This section describes the key memory items of Android
- How do I debug memory leaks
- Other tools
- analyse
- Related information recommendation
How do I view memory information? – Print in code, start a thread, print out the current memory information at fixed intervals.
private void startMemProfiler() { new Thread(new Runnable() { @Override public void run() { while (true) { displayMemory(); try { Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } } } }).start(); } private void displayMemory() { final ActivityManager activityManager = (ActivityManager) getSystemService(ACTIVITY_SERVICE); ActivityManager.MemoryInfo info = new ActivityManager.MemoryInfo(); activityManager.getMemoryInfo(info); The Log. I (TAG, "system memory remaining:" + (info. AvailMem/(1024 * 1024)) + "M"); Log. I (TAG, "is the system running lowMemory:" + info.lowmemory); Log. I (TAG, "low memory running when system free memory is lower than" + (info.threshold/(1024 * 1024)) + "M" + "); The Log i. (TAG, "systems have been allocated native memory:" + (Debug. GetNativeHeapAllocatedSize ()/(1024 * 1024)) + "M"); The Log i. (TAG, "system and the rest of the native memory:" + (Debug. GetNativeHeapFreeSize ()/(1024 * 1024)) + "M"); Log. I (TAG, "system native memory size:" + (debug.getnativeHeapSize ()/(1024 * 1024)) + "M"); }Copy the code
- Use the ADB command line
adb shell dumpsys meminfo /
adb shell dumpsys meminfo tv.danmaku.bili
Copy the code
Dumpsys Meminfo displays the following information:
This section describes the key memory items of Android
Here are just the fields we need to focus on:
- Dalvik Heap: memory occupied by the virtual machine, which can be understood as the memory occupied by the Java layer.
- Native Heap: memory occupied by the Native layer, which can be defined as memory occupied by the C/C++ side. [What we need to focus on]
- Private Dirty/Clean: The memory that is Private to the process and can be reclaimed after the process is destroyed
- Virtual Set Size (VSS) : indicates the Size of the entire memory address space accessible to a process. This size includes memory that the process has requested but not yet used. In practice, this method is rarely used to represent the memory usage of a process, and it is inaccurate to use it to represent the memory usage of a single process. [It’s not shown here, but Linux has this thing]
- Resident Set Size (RSS) : indicates the Size of the RAM used by a process, including the memory occupied by all shared libraries. The memory occupied by a process is also inaccurate. [It’s not shown here, but Linux has this thing]
- Proportional Set Size (PSS) : Indicates the actual space address Size used by a process in the RAM. It contains the memory occupied by the shared library in proportion. If there are three processes using the same shared library, the PSS of each process includes 1/3 of the shared library memory. This is an accurate representation of a process’s memory usage, but when only one process is using the shared library, it is exactly the same as RSS. One advantage of the PSS measure is that the PSS of all processes can be added together to determine the actual memory footprint of all processes. This means that PSS is an ideal way to measure the actual RAM footprint of a process, as well as its RAM footprint relative to other processes and the total RAM available.
- USS (Unique Set Size) : indicates the Size of the memory used by a process. This is the best way to indicate the Size of the memory used by a process. VSS>=RSS>=PSS>=USS
- Buffer queues are the memory used to display pixels (including GL surfaces, GL textures, and so on) to the screen. (Please note that this is CPU-shared memory, not GPU-dedicated memory.) The official document says, specific what meaning I didn’t understand, developer.android.com/studio/prof… 】
- The other fields if you want to know can refer to the official document: developer.android.com/studio/comm…
[Image upload failed…(image-18EC59-1636966209273)]
How do I debug memory leaks
- Through the elimination method + print the current memory information (described above) method, where suspected comment out, to see if there will be a leak.
- The code layer overwrites malloc and free globally, essentially recording every malloc node and storing it in the linked list. When free, the node is removed from the linked list. If there are still nodes in the last linked list, it indicates that there is a memory leak. It is useful in most scenarios, but can only detect the current code memory of C code, can not detect leaks in other libraries.
- Overloading operator new and operator delete works similarly. Malloc and free memory can only be detected if C++ uses new delete.
- Using Android Studio Profiler tools: need Android10 version above, specific can see: developer.android.com/studio/prof… 】
- By integrating Tencent /matrix on the Demo side, malloc and free symbols under a dynamic link library of Hook can be selected. If memory leakage is found in a dynamic link library, the leaked stack information will be printed. 【 Recommended use 】
The use of matrix
Through the integration of matrix library, malloc and free symbols of a dynamic link library can be selected in hook, and the working mode is similar to libcTools. Malloc nodes are stored, and the node is deleted when free, and the memory leakage situation is finally counted.
The integration method of matrix can be seen in github library: github.com/Tencent/mat…
The principle of hook can be seen: github.com/iqiyi/xHook…
If there is a memory leak, there will be json and log files, as shown:
Json files count which libraries leak how much memory, and log files record the stack information for specific leaks.
Once you have the specific leaked stack information, you can use the addr2line tool to locate the specific code:
/ Users/XXX/Android/the NDK / 21.4.7075529 / toolchains/LLVM/prebuilt/Darwin - x86_64 / bin/aarch64 - Linux - Android - addr2line - e - C - f /Users/xxx/project/java/build/intermediates/stripped_native_libs/debug/out/lib/arm64-v8a/libBMMCapture-Android.so 83a70Copy the code
The effect is as follows:
Other tools
Dumpsys has a few other features, which can be used as follows:
- Adb shell Dumpsys meminfo memory
- CPU adb shell dumpsys cpuinfo
- Adb shell Dumpsys gfxinfo frame rate
- Displays adb shell Dumpsys display
- Adb shell Dumpsys Power
- Battery status ADB shell Dumpsys BatteryStats
- Adb shell Dumpsys Battery
- Adb shell Dumpsys Alarm
- Adb shell Dumpsys location
[Image upload failed…(image-9afe5-1636966209271)]
Check for memory leakage
Background: Every time a memory leak occurs, it is often suspected that a module or other library update is to blame, but there is no proof and no proper methodology for detecting a memory leak.
Analysis and solution:
■ Access each tripartite library, write a Demo, effect test, memory test, performance test, each update tripartite library, run the Demo. Or every time something goes wrong, run the Demo to see if the library is causing the problem.
■ Third party library integration, reduce code coupling, ensure that you can flexibly remove a third party library, can consider the use of conditional compilation and other means, easy to troubleshoot problems.
■ Introduce tools to check:
○ Memory leak: Matrix is used for Android and Xcode is used for iOS
○ CPU usage: Android profiler and iOS Xcode
○gpu usage: Android qualcomm uses snapdragonprofiler, or perfdog (for a fee) reference
Developer.android.com/studio/comm…
Blog.csdn.net/pugongying1…
www.jianshu.com/p/8203457a1…