从“adb shell dumpsys meminfo my-app-name”中获取的文件详细说明。

15

有人能给我详细解释一下通过adb shell dumpsys meminfo my-app-name获取的profile是什么吗?

结果就像在如何在Android中发现我的应用程序使用的内存?中所提到的那样:

** MEMINFO in pid 890 [process-name] **
                    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
每一列(native、dalvik、other、total)的含义是什么?特别是“other”列是什么意思(除了native和dalvik之外我无法理解它是什么)?如果能给出一个具体的例子来阐述这个问题就更好了。例如,我有一个名为A的应用程序。A有自己的对象obj_private和自己的本地库lib_private。除此之外,A参考了Android框架的一些对象obj_shared和Android框架的一些本地库lib_shared。而obj_shared则参考了Android lib_shared_indirect的一些本地库。对于这种情况,我可以这样说吗?
1. “总大小”等于“obj_private + lib_private + obj_shared + lib_shared + lib_shared_indirect”所使用的所有内存。 2. “私有脏数据”等于“obj_private + lib_private”脏掉的内存。
我们想要澄清这个问题的原因是:我们最新版本的应用程序与以前版本相比存在一些异常的运行时内存增加。当我使用dumpsys meminfo命令时,发现“native”和“other”列大幅增加。但新版本的更改只涉及Java,并没有解释“other”列的变化。我在谷歌上搜索了一下,没有找到相关文档。我还尝试阅读adb的源代码,但像我这样的初学者很容易在源代码中迷失方向。因此,我在这里发布这个问题,希望有人能够帮助解答。

请查看https://dev59.com/63E95IYBdhLWcg3wd9tK。 - Shashank Tomar
1个回答

12
我们现在有更多关于Android内存使用的文档,详细说明了不同内存数字的含义:管理应用程序内存。特别是,在这里查看页面中间部分,讨论meminfo dump的关键部分:调查RAM使用情况
看起来您的meminfo输出是一个相当旧的Android版本,之前我们无法识别许多不同类型的分配。要将您所看到的映射到当前的文档,请仅将“其他”视为除本机和dalvik部分外现代dump显示的所有内容。在您的dump中,我相信您的dalvik部分实际上是将现代的“Dalvik Heap”和“Dalvik Other”结合在一起。
至于本机和其他部分仅因Java代码更改而不断增加,是的,这确实可能发生。 Android Java API的许多部分放在本地分配之上,并且还可以引起其他分配。这个典型的例子是Gingerbread及更早版本的位图,其中位图的数据是本地分配,而不像今天那样是Java堆中的数组分配。
您增加的其他分配可能是由很多事物造成的,就像您在最近版本的数据中看到的那样 - 支持光标的内存,来自ashmem的共享内存区域,设备为您分配的图形纹理等。有这么多事情可能会发生,很难说可能出了什么问题,这就是为什么现在的报告更详细的原因。(即使在那里,我们还有许多东西被折叠成未知。)
对于调试此问题,您可能需要查看Java堆中的泄漏对象。由于对象的实际分配不在Java堆中,因此当然可能有些棘手。我建议早期在应用程序中进行堆转储,在执行导致其RAM占用量增加的任何操作后进行堆转储,并查找哪些对象计数已增加。所引用的文档显示如何使用MAT比较堆转储。

此外,当您查看Java堆时,除了进行差异分析之外,一般情况下请务必遵循文档中指示的剥离堆中的zygote部分的步骤。正如文档所述,每个进程都有许多来自zygote的分配,但这些分配在所有进程之间共享,因此通常与堆分析无关。我经常看到人们感到担忧,因为他们在应用中看到了许多非常大的位图,并认为这是占用应用程序RAM的主要原因,但实际上这仅是来自zygote的共享分配。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接