如何在Android中发现我的应用程序的内存使用情况?

问题:

如何以编程方式找到我的Android应用程序使用的内存?
我希望有办法做到这一点。此外,如何获得手机的免费内存?

回答:

请注意,现代操作系统(如Linux)的内存使用是extremely复杂且难以理解的领域。事实上,你实际上正确地解释你获得的数字的机会是非常低的。 (几乎每次我和其他工程师一起看内存使用数字时,总是会讨论一下他们的意思,只会造成一个模糊的结论。)
 注意:我们现在有更广泛的文档
首先,大概阅读本文的最后一部分,讨论了如何在Android上管理内存:
 Service API changes starting with Android 2.0
现在,ActivityManager.getMemoryInfo()是查看整体内存使用情况的最高级别的API。这主要是为了帮助应用程序测量系统对于后台进程没有更多内存的需求,因此需要开始杀死所需的进程,如服务。对于纯Java应用程序,这应该没什么用,因为Java堆的限制在某种程度上是为了避免一个应用程序能够强调系统到这一点。
进入较低级别,您可以使用Debug API获取有关内存使用的原始内核级别信息:android.os.Debug.MemoryInfo
注意,从2.0开始,还有一个API ActivityManager.getProcessMemoryInfo来获取有关另一个进程的信息:ActivityManager.getProcessMemoryInfo(int[])
这将返回具有所有这些数据的低级别的MemoryInfo结构:

    /** 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;

但是,在PssPrivateDirtySharedDirty之间有什么区别呢?现在,乐趣开始了。
Android(和一般的Linux系统)中的大量内存实际上是跨多个进程共享的。那么进程使用多少内存真的不清楚。将该分页放在磁盘上(更不用说我们不在Android上使用的交换),而且还不甚清楚。
因此,如果要将所有物理RAM实际映射到每个进程,并将所有进程相加,则可能会得到比实际总RAM大得多的数据。
Pss数字是内核计算考虑到内存共享的度量标准,基本上每个进程内的RAM页面都是通过使用该页面的其他进程的数量进行比例缩放。这样,您可以(理论上)将所有进程中的pss加起来,以查看它们正在使用的总RAM,并比较进程之间的pss,以了解它们的相对权重。
另一个有趣的指标是PrivateDirty,这基本上是进程内RAM不能被分页到磁盘的数量(它不是由磁盘上的相同数据支持),并且不与任何其他进程共享。另一种看待这种情况的方法是当该过程消失时(可能很快将其包含在高速缓存和其他用途中)可用于系统的RAM。
这就是SDK API。但是您可以使用设备的开发人员做更多的工作。
使用adb,有很多关于正在运行的系统的内存使用的信息。一个常见的是命令adb shell dumpsys meminfo,它将吐出一堆关于每个Java进程的内存使用的信息,其中包含上述信息以及各种其他内容。您还可以点击单个进程的名称或pid来查看,例如adb shell dumpsys meminfo system给我系统过程:

** 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

顶部是主要的,其中size是特定堆的地址空间中的总大小,allocated是堆认为的实际分配的kb,free堆有剩余的kb的空闲空间对于额外的分配,psspriv dirty与在与每个堆相关联的页面具体之前讨论的相同。
如果只想查看所有进程的内存使用情况,可以使用命令adb shell procrank。在同一系统上的输出如下所示:

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

这里,VssRss列基本上是噪声(这些是进程的直接地址空间和RAM使用情况,如果将进程中的RAM使用量加起来可以获得一个可笑的大数)。
 Pss如前所述,UssPriv Dirty
有趣的事情要注意:PssUss略微(或略微)不同于我们在meminfo中看到的。这是为什么? procrank使用不同的内核机制来收集其数据,而不是meminfo,并且给出稍微不同的结果。这是为什么?老实说,我没有线索。我相信procrank可能是更准确的一个…但是真的,这只是留下一点:“拿任何记忆信息,你得到一粒盐,通常是一个非常大的粮食。
最后还有一个命令adb shell cat /proc/meminfo,总结了系统的整体内存使用情况。这里有很多数据,只有前几个数字值得讨论(其余的几个人都知道,我对这几个人的疑问经常导致矛盾的解释):

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

 MemTotal是可用于内核和用户空间的总内存量(通常小于设备的实际物理RAM),因为无线电,DMA缓冲区等需要某些RAM)。
 MemFree是没有被使用的RAM的数量。你在这里看到的数字很高;通常在Android系统上,这将只有几MB,因为我们尝试使用可用内存来保持进程的运行
 Cached是用于文件系统缓存和其他这样的东西的RAM。典型的系统需要20MB左右才能避免进入不良的寻呼状态;针对特定系统调整了Android内存不足,以确保后台进程在高速缓存的RAM被它们消耗太多以致导致这种分页之前被杀死。

 
 
Code问答: http://codewenda.com/topics/python/
Stackoverflow: How do I discover memory usage of my application in Android?

*转载请注明本文链接以及stackoverflow的英文链接

发表评论

电子邮件地址不会被公开。 必填项已用*标注

3 + 7 =