Note that memory usage on modern operating systems like Linux is an extremely complicated and difficult to understand area. In fact the chances of you actually correctly interpreting whatever numbers you get is extremely low. (Pretty much every time I look at memory usage numbers with other engineers, there is always a long discussion about what they actually mean that only results in a vague conclusion.)

Note: we now have much more extensive documentation on Managing Your App's Memorythat covers much of the material here and is more up-to-date with the state of Android.

First thing is to probably read the last part of this article which has some discussion of how memory is managed on Android:

Service API changes starting with Android 2.0

Now ActivityManager.getMemoryInfo() is our highest-level API for looking at overall memory usage. This is mostly there to help an application gauge how close the system is coming to having no more memory for background processes, thus needing to start killing needed processes like services. For pure Java applications, this should be of little use, since the Java heap limit is there in part to avoid one app from being able to stress the system to this point.

Going lower-level, you can use the Debug API to get raw kernel-level information about memory usage: android.os.Debug.MemoryInfo

Note starting with 2.0 there is also an API, ActivityManager.getProcessMemoryInfo, to get this information about another process: ActivityManager.getProcessMemoryInfo(int[])

This returns a low-level MemoryInfo structure with all of this data:

     /** The proportional set size for dalvik. */
public int dalvikPss;
/** The private dirty pages used by dalvik. */
public int dalvikPrivateDirty;
/** The shared dirty pages used by dalvik. */
public int dalvikSharedDirty; /** The proportional set size for the native heap. */
public int nativePss;
/** The private dirty pages used by the native heap. */
public int nativePrivateDirty;
/** The shared dirty pages used by the native heap. */
public int nativeSharedDirty; /** The proportional set size for everything else. */
public int otherPss;
/** The private dirty pages used by everything else. */
public int otherPrivateDirty;
/** The shared dirty pages used by everything else. */
public int otherSharedDirty;

But as to what the difference is between PssPrivateDirty, and SharedDirty... well now the fun begins.

A lot of memory in Android (and Linux systems in general) is actually shared across multiple processes. So how much memory a processes uses is really not clear. Add on top of that paging out to disk (let alone swap which we don't use on Android) and it is even less clear.

Thus if you were to take all of the physical RAM actually mapped in to each process, and add up all of the processes, you would probably end up with a number much greater than the actual total RAM.

The Pss number is a metric the kernel computes that takes into account memory sharing -- basically each page of RAM in a process is scaled by a ratio of the number of other processes also using that page. This way you can (in theory) add up the pss across all processes to see the total RAM they are using, and compare pss between processes to get a rough idea of their relative weight.

The other interesting metric here is PrivateDirty, which is basically the amount of RAM inside the process that can not be paged to disk (it is not backed by the same data on disk), and is not shared with any other processes. Another way to look at this is the RAM that will become available to the system when that process goes away (and probably quickly subsumed into caches and other uses of it).

That is pretty much the SDK APIs for this. However there is more you can do as a developer with your device.

Using adb, there is a lot of information you can get about the memory use of a running system. A common one is the command adb shell dumpsys meminfo which will spit out a bunch of information about the memory use of each Java process, containing the above info as well as a variety of other things. You can also tack on the name or pid of a single process to see, for example adb shell dumpsys meminfo system give me the system process:

** MEMINFO in pid 890 [system] **
native dalvik other total
size: 10940 7047 N/A 17987
allocated: 8943 5516 N/A 14459
free: 336 1531 N/A 1867
(Pss): 4585 9282 11916 25783
(shared dirty): 2184 3596 916 6696
(priv dirty): 4504 5956 7456 17916 Objects
Views: 149 ViewRoots: 4
AppContexts: 13 Activities: 0
Assets: 4 AssetManagers: 4
Local Binders: 141 Proxy Binders: 158
Death Recipients: 49
OpenSSL Sockets: 0 SQL
heap: 205 dbFiles: 0
numPagers: 0 inactivePageKB: 0
activePageKB: 0

The top section is the main one, where size is the total size in address space of a particular heap, allocated is the kb of actual allocations that heap thinks it has, free is the remaining kb free the heap has for additional allocations, and pss and priv dirty are the same as discussed before specific to pages associated with each of the heaps.

If you just want to look at memory usage across all processes, you can use the command adb shell procrank. Output of this on the same system looks like:

  PID      Vss      Rss      Pss      Uss  cmdline
890 84456K 48668K 25850K 21284K system_server
1231 50748K 39088K 17587K 13792K com.android.launcher2
947 34488K 28528K 10834K 9308K com.android.wallpaper
987 26964K 26956K 8751K 7308K com.google.process.gapps
954 24300K 24296K 6249K 4824K com.android.phone
948 23020K 23016K 5864K 4748K com.android.inputmethod.latin
888 25728K 25724K 5774K 3668K zygote
977 24100K 24096K 5667K 4340K android.process.acore
...
59 336K 332K 99K 92K /system/bin/installd
60 396K 392K 93K 84K /system/bin/keystore
51 280K 276K 74K 68K /system/bin/servicemanager
54 256K 252K 69K 64K /system/bin/debuggerd

Here the Vss and Rss columns are basically noise (these are the straight-forward address space and RAM usage of a process, where if you add up the RAM usage across processes you get an ridiculously large number).

Pss is as we've seen before, and Uss is Priv Dirty.

Interesting thing to note here: Pss and Uss are slightly (or more than slightly) different than what we saw in meminfo. Why is that? Well procrank uses a different kernel mechanism to collect its data than meminfo does, and they give slightly different results. Why is that? Honestly I haven't a clue. I believe procrank may be the more accurate one... but really, this just leave the point: "take any memory info you get with a grain of salt; often a very large grain."

Finally there is the command adb shell cat /proc/meminfo that gives a summary of the overall memory usage of the system. There is a lot of data here, only the first few numbers worth discussing (and the remaining ones understood by few people, and my questions of those few people about them often resulting in conflicting explanations):

MemTotal:         395144 kB
MemFree: 184936 kB
Buffers: 880 kB
Cached: 84104 kB
SwapCached: 0 kB

MemTotal is the total amount of memory available to the kernel and user space (often less than the actual physical RAM of the device, since some of that RAM is needed for the radio, DMA buffers, etc).

MemFree is the amount of RAM that is not being used at all. The number you see here is very high; typically on an Android system this would be only a few MB, since we try to use available memory to keep processes running

Cached is the RAM being used for filesystem caches and other such things. Typical systems will need to have 20MB or so for this to avoid getting into bad paging states; the Android out of memory killer is tuned for a particular system to make sure that background processes are killed before the cached RAM is consumed too much by them to result in such paging

Android MemInfo的更多相关文章

  1. Android MemInfo 各项的意义(转)

    http://gdgzzch.blog.163.com/blog/static/37640452201371483147573/ http://stackoverflow.com/questions/ ...

  2. Android使用procrank和dumpsys meminfo 、top分析内存占用情况

    如果你想查看所有进程的内存使用情况,可以使用命令procrank.dumpsys meminfo查看,当然也只可以过滤出某个进程如:dumpsys meminfo | grep -i phone 先来 ...

  3. Android内存优化—dumpsys meminfo详解

    原创置顶 不死鸟JGC 最后发布于2018-12-24 14:19:28 阅读数 3960 收藏展开dumpsys 介绍Dumpsys用户系统诊断,它运行在设备上,并提供系统服务状态信息 命令格式: ...

  4. Android中proc/meminfo的详解(原)

    今天在写到获取手机可用内存空间的总大小的时候,通过下面的方法去获取的时候,发现该方法最低支持的版本是16,这显然是不可取的. public static long getTotalSpace(Cont ...

  5. android adb 命令详解

    ADB (Android Debug Bridge)  是android SDK中的工具,需要先配置环境变量才能使用.起调试桥的作用,可以管理安卓设备.(也叫debug工具) ---------查看设 ...

  6. android 腾讯x5内核 浏览器

    1.浏览器内核: 主流浏览器内核介绍(前端开发值得了解的浏览器内核历史) 浏览器内核历史介绍: 在android 4.4之前,浏览器用的还是webkit 在android 4.4之后,google就抛 ...

  7. Android应用性能优化(转)

    人类大脑与眼睛对一个画面的连贯性感知其实是有一个界限的,譬如我们看电影会觉得画面很自然连贯(帧率为24fps),用手机当然也需要感知屏幕操作的连贯性(尤其是动画过度),所以Android索性就把达到这 ...

  8. Android ANR 分析解决方法

    一:什么是ANR ANR:Application Not Responding,即应用无响应 二:ANR的类型 ANR一般有三种类型: 1. KeyDispatchTimeout(5 seconds) ...

  9. How to Use Android ADB Command Line Tool

    Android Debug Bridge (adb) is a tool that lets you manage the state of an emulator instance or Andro ...

随机推荐

  1. JAVA基础--日期处理

    用SimpleDateFormat方法格式化日期格式: package DAO; import java.sql.Connection; import java.sql.DriverManager; ...

  2. source command not found in sh shell解决办法

    在Ubuntu系统中执行脚本的时候突然出现错误"source command not found in sh shell" 这个其实在Ubuntu 当中 执行脚本默认的使用的是da ...

  3. webservice-概念性学习(一)

    以下是本人原创,如若转载和使用请注明转载地址.本博客信息切勿用于商业,可以个人使用,若喜欢我的博客,请关注我,谢谢!博客地址 学习webservice之前呢,我想说我们先学习以下的知识,对你以后的学习 ...

  4. LPC1768的USB使用--宏定义

    #ifndef __USBREG_H #define __USBREG_H /* usb设备中断定义 usb_devintst usb_devinten usb_devintclr usb_devin ...

  5. STM8的中断系统以及外部中断详解

    STM8具有最多32的中断系统,在中断的处理上类似于cortexm系列的芯片,首先是每个中断的向量都是固化在系统内部的,用户需要向相应的中断向量flash位置写入中断处理函数,其二,每个中断向量都具有 ...

  6. 微信小程序之----组件

    1.view 把文档分割为独立的.不同的部分. view组件类似于html中的div标签,默认为块级元素,独占一行,可以通过设置display:inline-block改为行级元素. view.wxm ...

  7. C++类的存储(部分可用与c的结构体)

    c++中最重要的就是类,那么给你一个类的对象,你知道它在内存中如何存储的吗?它占内存中多少个字节? 首先确定类的构成: 1,数据成员:可以是内置类型,类类型. 2,函数成员:虚函数,非虚函数 1)数据 ...

  8. Jquery插件之ajaxForm ajaxSubmit的理解用法

      如今ajax满天飞,作为重点的form自然也受到照顾. 其实,我们在平常使用Jquery异步提交表单,一般是在submit()中,使用$.ajax进行.比如:   $(function(){ $( ...

  9. 输入计算表达式,将他们存在string【】中

    #include<stdio.h>#include<string>#include<string.h>#include<stdlib.h>#includ ...

  10. 聊聊Node.js 独立日漏洞

    背景 Node.js 社区近期在美国独立日周末的狂欢之时爆出漏洞 https://medium.com/@iojs/important-security-upgrades-for-node-js-an ...