How do I discover memory usage of my application in Android?

前端 未结 9 2311
清酒与你
清酒与你 2020-11-21 06:27

How can I find the memory used on my Android application, programmatically?

I hope there is a way to do it. Plus, how do I get the free memory of the phone too?

9条回答
  •  慢半拍i
    慢半拍i (楼主)
    2020-11-21 06:55

    We found out that all the standard ways of getting the total memory of the current process have some issues.

    • Runtime.getRuntime().totalMemory(): returns JVM memory only
    • ActivityManager.getMemoryInfo(), Process.getFreeMemory() and anything else based on /proc/meminfo - returns memory info about all the processes combined (e.g. android_util_Process.cpp)
    • Debug.getNativeHeapAllocatedSize() - uses mallinfo() which return information about memory allocations performed by malloc() and related functions only (see android_os_Debug.cpp)
    • Debug.getMemoryInfo() - does the job but it's too slow. It takes about 200ms on Nexus 6 for a single call. The performance overhead makes this function useless for us as we call it regularly and every call is quite noticeable (see android_os_Debug.cpp)
    • ActivityManager.getProcessMemoryInfo(int[]) - calls Debug.getMemoryInfo() internally (see ActivityManagerService.java)

    Finally, we ended up using the following code:

    const long pageSize = 4 * 1024; //`sysconf(_SC_PAGESIZE)`
    string stats = File.ReadAllText("/proc/self/statm");
    var statsArr = stats.Split(new [] {' ', '\t', '\n'}, 3);
    
    if( statsArr.Length < 2 )
        throw new Exception("Parsing error of /proc/self/statm: " + stats);
    
    return long.Parse(statsArr[1]) * pageSize;
    

    It returns VmRSS metric. You can find more details about it here: one, two and three.


    P.S. I noticed that the theme still has a lack of an actual and simple code snippet of how to estimate the private memory usage of the process if the performance isn't a critical requirement:

    Debug.MemoryInfo memInfo = new Debug.MemoryInfo();
    Debug.getMemoryInfo(memInfo);
    long res = memInfo.getTotalPrivateDirty();
    
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) 
        res += memInfo.getTotalPrivateClean(); 
    
    return res * 1024L;
    

提交回复
热议问题