美文网首页Android科普知识库
盘点|统计Android内存使用的方法有哪些?

盘点|统计Android内存使用的方法有哪些?

作者: 蚍蜉一生 | 来源:发表于2024-05-23 18:04 被阅读0次

    内存的定量分析是我们了解App性能、系统健康度,解决ANR、OOM,进行系统和App优化的重要指标。本文就盘点下当前有哪些统计Android内存使用量的方法。

前置知识

RSS - Resident Set Size 实际使用物理内存(包含共享库占用的内存)
PSS - Proportional Set Size 实际使用的物理内存(比例分配共享库占用的内存)


运行时内存分布

内存统计方法

一、adb命令

1.1 adb shell dumpsys meminfo packageName

dumpsys meminfo
1.2 adb shell top
top获取

二、Android studio profiler

Android studio->profiler->SESSIONS+选择特定应用

as profiler

三、代码中获取

3.1 通过Runtime获取

// App进程的虚拟机可使用最大内存,不包括Nativie
int maxMemory = (int) (Runtime.getRuntime().maxMemory() / (1024*1024)); 
// App进程的虚拟机已经申请到的内存 
int totalMemory= (int) (Runtime.getRuntime().totalMemory() / (1024*1024)); 
// App进程虚拟机已申请到但还未使用的内存
int freeMemory=(int)(Runtime.getRuntime().freeMemory() / (1024*1024)); 
// App java层已经使用的内存
int useMemoryOnJava = totalMemory - freeMemory;
Log.d("MemoryInfo", "this app's JVM can use Max java memory is " + maxMemory + "MB");
Log.d("MemoryInfo", "this app's JVM now get Total memory is " + totalMemory + "MB");
Log.d("MemoryInfo", "this app's JVM now freeMemory memory is " + freeMemory + "MB");
Log.d("MemoryInfo", "this app's JVM now use memory is " + useMemoryOnJava + "MB");

3.2 通过ActivityManager获取

ActivityManager activityManager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);

// 该设备整体内存情况
ActivityManager.MemoryInfo systemMemoryInfo = new ActivityManager.MemoryInfo();
activityManager.getMemoryInfo(systemMemoryInfo);
long sysTotalMemory = systemMemoryInfo.totalMem / (1024 * 1024);
long sysAvailableMemory = systemMemoryInfo.availMem / (1024 * 1024);
// 系统内存阈值,低于这个阈值,系统就要进行清理后台进程等操作
long sysThreshold = systemMemoryInfo.threshold / (1024 * 1024);
boolean sysNowIsLowMemory = systemMemoryInfo.lowMemory;
Log.d("MemoryInfo", "system Total Memory: " + sysTotalMemory  + " MB");
Log.d("MemoryInfo", "system Available Memory: " +sysAvailableMemory + " MB");
Log.d("MemoryInfo","system Threshold: " + sysThreshold + " MB");
Log.d("MemoryInfo", "system now is Low Memory: " + sysNowIsLowMemory);

// 对每个App的java堆限制
int largeMemoryClass = activityManager.getLargeMemoryClass();
Log.d("MemoryInfo", "设置android:largeHeap=\"true\" , App Max memory is " + largeMemoryClass + "MB");
int memoryClass = activityManager.getMemoryClass();
Log.d("MemoryInfo", "App max memory is " + memoryClass + "MB");

// 获取本进程使用的内存情况值
int pid = android.os.Process.myPid();
int[] pids = new int[]{pid};
Debug.MemoryInfo[] memoryInfoArray = activityManager.getProcessMemoryInfo(pids);
Debug.MemoryInfo memoryInfo = memoryInfoArray[0];
// 获取总内存使用 它等于dalvikPss + nativePss + otherPss + TotalSwappedOutPss
int totalPss = memoryInfo.getTotalPss()/1024;
int totalPrivateDirty = memoryInfo.getTotalPrivateDirty()/1024;
int totalSharedDirty = memoryInfo.getTotalSharedDirty()/1024;

// 获取 Native 堆内存
int nativePss = memoryInfo.nativePss/1024;
int nativePrivateDirty = memoryInfo.nativePrivateDirty/1024;
int nativeSharedDirty = memoryInfo.nativeSharedDirty/1024;

// 获取 Dalvik 堆内存
int dalvikPss = memoryInfo.dalvikPss/1024;
int dalvikPrivateDirty = memoryInfo.dalvikPrivateDirty/1024;
int dalvikSharedDirty = memoryInfo.dalvikSharedDirty/1024;

Log.d("MemoryInfo", "Total PSS: " + totalPss + " MB");
Log.d("MemoryInfo", "Total Private Dirty: " + totalPrivateDirty + " MB");
Log.d("MemoryInfo", "Total Shared Dirty: " + totalSharedDirty + " MB");

Log.d("MemoryInfo", "Native PSS: " + nativePss + " MB");
Log.d("MemoryInfo", "Native Private Dirty: " + nativePrivateDirty + " MB");
Log.d("MemoryInfo", "Native Shared Dirty: " + nativeSharedDirty + " MB");

Log.d("MemoryInfo", "Dalvik PSS: " + dalvikPss + " MB");
Log.d("MemoryInfo", "Dalvik Private Dirty: " + dalvikPrivateDirty + " MB");
Log.d("MemoryInfo", "Dalvik Shared Dirty: " + dalvikSharedDirty + " MB");

疑问和思考

    问题: 实际测试时候,用上述几种方法同时去获取内存占用情况,发现同一个指标大概率能发现有较大差距,为什么呢?
    个人理解:虚拟机启动时候必须是有一套内存管理方案的,各个方法也是通过不同的通信方式或者api从虚拟机内存管理方获取这些信息,不同的原因在于内存波动很快,不同统计方法获取原始数据后计算方法不同等原因;还有可能就是不同指标虽然暴露对上层意思相近,但是实际上代表不同的含义,这个还有待研究,了解这个的大佬可以评论区交流。
    注意事项:目前我们搞内存优化,等需要量化内存场景的时候需要确定好是使用哪种方法进行测试,并且需要通过多次获取求均值等方法进行。

相关文章

  • linux性能优化

    一:总述:有哪些优化方面 IO CPU 磁盘 内存 二:工具 2.1 内存 vmstat 虚拟内存统计,可对操作...

  • JVM 面试题

    JVM内存 1、JVM方法区存储内容 是否会动态扩展,是否会出现内存溢出,出现的原因有哪些?2、JVM内存分为哪些...

  • Android性能分析

    Android内存优化之一:MAT使用入门 · Android Performance Android内存优化之二...

  • android 内存问题处理资源整理

    Android最佳性能实践(二)——分析内存的使用情况 android内存管理建议译文 android内存泄露总结...

  • 2017.12.27三题

    1.Android线程间通信有哪些方式? 共享变量(内存) 管道 handler机制:runOnUiThread(...

  • Handler与内存泄露

    参考:Android使用Handler造成内存泄露的分析及解决方法 > https://www.cnblogs.c...

  • 艺术开发探索十五章笔记

    Android性能优化 Android不可能无限制的使用内存和CPU资源,过多的使用内存会导致内存溢出,即OOM。...

  • 优化

    1.内存溢出和内存泄漏有什么区别?何时会产生内存泄漏?内存优化有哪些方法? 内存溢出通俗理解就是软件(应用)运行需...

  • 测试app性能方式

    【方法一】android端使用adb命令 adb dumpsys命令,查看应用程序内存使用情况 1、CPU:adb...

  • Android内存简括

    Android手机对应用都有个最大内存使用限制 Android代码中内存使用注意点 String拼接采用Strin...

网友评论

    本文标题:盘点|统计Android内存使用的方法有哪些?

    本文链接:https://www.haomeiwen.com/subject/bbitqjtx.html