Cut the crap and get straight to the dry stuff.

1: The way code works

Use Debug getMemoryInfo(debug.memoryInfo MemoryInfo) or ActivityManager MemoryInfo[] getProcessMemoryInfo(int[] pids) in code

ActivityManager mAm = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
Debug.MemoryInfo[] memoryInfoArray = mAm.getProcessMemoryInfo(pids);
Copy the code

The MemoryInfo object provides detailed memory information, such as doraemon, GT, and so on. This way is simple and convenient

2: dumpsys command

adb shell dumpsys meminfo package_name|pid
Copy the code

PSS columns:

  • Native Heap: memory in the JNI layer
  • Dalvik Heap: Memory allocation in the Java layer
  • Total PSS: the actual memory occupied by the application

This is the way most corporate tests fetch in-memory data

3: indicates the SMaps file

Linux since version 2.6 has a proc pseudo file that records various information, where in proc/pid/smaps records a PID, smaps records memory usage details. Use the following command to read the value of the file

cat /proc/pid/smaps
Copy the code

The file format is as follows:

  • 400CA000-400CB000: indicates the address range of the virtual memory
  • R-xp: indicates the file permission. R (read), W (write), x (execute), and P indicate private files. S indicates shared files
  • 00000000: indicates the offset of the mapping file
  • B3:11: indicates the file device number
  • 1345: An enantile node mapped to a virtual memory file
  • / system/lib/libplddbgutil. So: the file name
  • Size: indicates the Size of the corresponding virtual address space
  • RSS: The size of the physical memory being used
  • Shared_Clean: Number of unused pages that Rss shares with other processes
  • Shared_Dirty: Rss shares the number of pages that have been used with other processes
  • Private_Clean: number of unused pages in the Rss private area
  • Private_Dirty: Number of pages that have been used in the Rss private area

For example, when we get the memory through Dumpsys meminfo, we find a certain memory data is abnormal. In order to find out which files generate the data, we can read the SMaps file to make a detailed investigation.

4: source code analysis

Dumpsys memInfo: dumpsys memInfo: dumpsys memInfo: dumpsys memInfo: Dumpsys memInfo: Dumpsys memInfo: Dumpsys memInfo: Dumpsys memInfo: Dumpsys memInfo: Dumpsys memInfo: Dumpsys memInfo: Dumpsys memInfo: Dumpsys memInfo: Dumpsys memInfo: Dumpsys memInfo: Dumpsys memInfo: Dumpsys memInfo Dump service.

That we pass into memInfo which is corresponding to the service, which we need to look at ActivityManagerService. Java classes, search memInfo, finally we found it was MemBinder corresponding service.

Let’s click on the MemBinder class to see the implementation inside the class

Method will first for android. The Manifest. Permission. DUMP permission check, call dumpApplicationMemoryUsage method, finally we see dumpApplicationMemoryUsage method do what operation

This method is quite extensive, and we only show where it ends up, and we eventually find that the android.os.debug.java class ends up being called.

Java Native file android_os_debug.cpp, android_os_debug.cpp, android_os_debug.cpp, android_os_debug.cpp, android_os_debug.cpp, android_os_debug.cpp, android_os_debug.cpp The debug.getMemoryInfo (PID, mi) above actually calls the android_OS_DEBUg.cpp method android_os_Debug_getDirtyPagesPid last

The android_os_Debug_getDirtyPagesPid method calls the load_maps(int PID, stats_t* stats) method

Load_maps is done by reading the contents of smaps files, where dumpsys memInfo’s implementation becomes clear.

The first code implementation way, in fact, the final process is the same as the above.

CPP address: android_OS_debug. CPP file

5: Points of concern for memory testing

1. Whether the memory continues to increase: Whether the memory increases when entering a function and decreases when exiting the function

2. Frequent GC: Frequent GC can be caused by memory fragmentation in your application, which is another area that needs to be optimized

3. Check whether the memory peak value is within the maximum allowed value for a single application