15

谁能给我详细解释一下获得的个人资料adb shell dumpsys meminfo my-app-name

结果与如何在 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)是什么意思?尤其是“其他”列是什么(我不知道除了原生和 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有关,“其他”栏目没有说明。我用谷歌搜索了这个并没有找到任何文件。我还尝试阅读 adb 的源代码。但是我发现像我这样的新手很容易迷失在源代码中。所以我在这里发布这个问题,以防有人可以提供帮助。

4

1 回答 1

11

我们现在有更多关于 Android 中 RAM 使用的文档,其中详细介绍了不同 RAM 数字的含义:管理您的应用程序的内存。特别是,请查看此处讨论 meminfo 转储关键部分的页面中间:调查您的 RAM 使用情况

在我们识别出许多不同类型的分配之前,您的 meminfo 输出看起来像是来自相当旧的 Android 版本。要将您所看到的内容映射到当前文档,只需将“其他”视为现代转储显示的除本机和 dalvik 部分之外的所有内容。在您的转储中,我相信您的 dalvik 部分实际上是现代的“Dalvik Heap”和“Dalvik Other”放在一起。

就本机和其他部分而言,仅在 Java 代码更改之后越来越多,是的,这肯定会发生。Android Java API 的许多部分位于本机分配之上,也可能导致其他分配。这方面的经典示例是 Gingerbread 和更早版本上的位图,其中位图的数据是本机分配,而不是像今天这样在 Java 堆中的数组分配。

您增加的其他分配可能是由于您将在最新版本的数据中看到的许多事情 - 内存支持游标,来自ashmem的共享内存区域,为您分配事物的设备,例如图形纹理等。有很多事情很难说会发生什么,这就是为什么这些天报告更加详细的原因。(即使在那里,我们仍然有很多东西被淹没在未知中。)

为了调试它,您可能想查看 Java 堆中是否有泄漏的对象。由于对象的实际分配不在 Java 堆中,这当然会很棘手。我建议在你的应用程序早期进行堆转储,做任何导致其 RAM 占用增加的事情,之后进行堆转储,并查看哪些对象计数增加了。参考文档显示了如何将堆转储与 MAT 进行比较。

此外,当您将 Java 堆视为一般分析时(除了进行差异分析时),请始终确保按照那里的说明去除堆的 zygote 部分。正如文档所述,每个进程都有大量来自 zygote 的分配,但这些分配在所有进程之间共享,因此通常与堆分析无关。我经常看到有人担心,因为他们在他们的应用程序中看到很多非常大的位图,系统似乎已经分配给他们,并认为这是在他们的应用程序中使用 RAM 的主要事情,如果不是,那只是zygote 的共享分配。

于 2013-11-12T02:24:09.307 回答