ActivityManager.MemoryInfo

在代码中,ActivityManager给开发者提供了ActivityManager.MemoryInfo类,用于封装系统级别的内存数据,它包含以下几种数据。

  • totalMem:系统可用总内存。
  • availMem:系统当前剩余内存。
  • lowMemory:是否处于低内存状态。
  • threshold:内存阈值。

代码中使用方法如下所示。

  1. ActivityManager am = (ActivityManager)
  2. context.getSystemService(Activity.ACTIVITY_SERVICE);
  3. ActivityManager.MemoryInfo memoryInfo = new ActivityManager.MemoryInfo();
  4. am.getMemoryInfo(memoryInfo);
  5.  
  6. Log.d("test", "系统可用总内存:" + formatData(context, memoryInfo.totalMem));
  7. Log.d("test", "系统当前剩余内存:" +
  8. formatData(context, memoryInfo.availMem));
  9. Log.d("test", "是否处于低内存状态:" + memoryInfo.lowMemory);
  10. Log.d("test", "内存阈值:" + formatData(context, memoryInfo.threshold));
  11.  
  12. /**
  13. * 格式化数据
  14. *
  15. * @param context context
  16. * @param fileData data(byte)
  17. * @return 格式化数据(KB MB GB)
  18. */
  19. public static String formatData(Context context, long fileData) {
  20. return Formatter.formatFileSize(context, fileData);
  21. }

运行后Log显示如下所示。

  1. D/test: 系统总内存1.79GB
  2. D/test: 系统剩余内存1.12GB
  3. D/test: 是否处于低内存false
  4. D/test: 内存阈值220MB

当内存处于低内存状态时,就会触发Android系统的LMK——Low Memory Kill杀死一些优先级低的进程来释放内存空间。

需要注意的是,这里给出的基本是系统级别的内存数据。对于每个应用来说,通过ActivityManager还可以获取每个App的最大可分配内存即OOM上限,代码如下所示。

  1. Log.d("test", "单个App内存最大值:" + am.getMemoryClass() + "MB");
  2. Log.d("test", "单个App内存最大值(申请large heap):" + am.getLargeMemoryClass() + "MB");

运行后Log显示如下所示。

  1. D/test: 单个App内存最大值:192MB
  2. D/test: 单个App内存最大值(申请large heap):512MB

large heap即在AndroidMainifest文件中申请的android:largeHeap="true"属性。

这些阈值是定义在系统ROM中的,在编译时就已经写入系统了,通过查看系统属性,你可以找到这些值,例如单个App的内存最大值。

  1. ~ adb shell getprop | grep dalvik.vm.heapgrowthlimit
  2. [dalvik.vm.heapgrowthlimit]: [192m]

ActivityManager.MemoryInfo - 图1large heap属性虽然确实可以提高App的分配内存,但也会造成由于内存过大而导致的GC速度减慢,因此建议大家不要使用这种“伤敌一千,自损八百”的方法。

另外,这里得到的一些内存阈值与ROM是强相关的,不同的手机获取的值是不同的。