3

我有一个 Android 活动BrowseActivity,它将大约 3000 条记录(@ 大约 100 字节)从数据库加载到内存中,并以ListView. 在 AVD 中加载大约需要 3 到 6 秒,这很好。

当我想从这里开始一个新活动时,问题就出现了BrowseActivity。即使只是打开最琐碎的活动,也需要大约 30 秒。Dalvik VM 似乎做了很多垃圾收集,原因不明。请检查logcat下面的输出。

01-30 02:06:27.025: D/dalvikvm(553): GC_FOR_MALLOC freed 3889 objects / 221200 bytes in 45ms
01-30 02:06:28.234: D/dalvikvm(553): GC_FOR_MALLOC freed 2784 objects / 76864 bytes in 48ms
01-30 02:06:29.614: D/dalvikvm(553): GC_FOR_MALLOC freed 2665 objects / 70088 bytes in 64ms
01-30 02:06:30.915: D/BrowseActivity(553): Low memory status: false
01-30 02:06:30.915: D/BrowseActivity(553): Low memory threshold (KB): 16384
01-30 02:06:30.915: D/BrowseActivity(553): Memory available (KB): 451348
01-30 02:06:31.095: D/dalvikvm(553): GC_EXTERNAL_ALLOC freed 2711 objects / 85904 bytes in 62ms
01-30 02:06:49.705: D/dalvikvm(553): GC_FOR_MALLOC freed 8894 objects / 600272 bytes in 89ms
01-30 02:06:50.414: D/dalvikvm(553): GC_FOR_MALLOC freed 10757 objects / 730720 bytes in 68ms
01-30 02:06:51.105: D/dalvikvm(553): GC_FOR_MALLOC freed 10251 objects / 694864 bytes in 67ms
... and about 30 more garbage collection messages

我已经尝试过使用较少的记录数:1 和 300。它导致垃圾收集消息(分别为 1 和 7)和更快的活动负载(分别为 1 和 6 秒),但内存可用性差异是很简单:

01-30 02:03:35.295: D/BrowseActivity(491): Low memory status: false
01-30 02:03:35.295: D/BrowseActivity(491): Low memory threshold (KB): 16384
01-30 02:03:35.295: D/BrowseActivity(491): Memory available (KB): 453184

01-30 02:04:53.494: D/BrowseActivity(522): Low memory status: false
01-30 02:04:53.494: D/BrowseActivity(522): Low memory threshold (KB): 16384
01-30 02:04:53.494: D/BrowseActivity(522): Memory available (KB): 453152

似乎缓慢的活动加载时间是由 GC 开销引起的。我的问题是:为什么 Dalvik VM 会做很多 GC?即使有 3000 条记录,我相信它也只需要 500 KB 的内存。如果不是关于 GC 开销,那么这种缓慢的活动负载的其他可能原因是什么?

作为记录,我使用内置类ActivityManager.MemoryInfo提供的信息记录了内存可用性。

4

1 回答 1

1

我认为您没有引用包含 3000 条记录的 Activity,这会导致在您更改 Activity 时激活 GC。

如果您使用 MVC 类型模式并且有一个引用每个 Activity 的控制器,我认为 GC 不会清理这些记录。当内存部分存在但没有已知的引用时,GC 就会启动,一旦切换活动,对活动的引用及其所有函数和成员变量都不再使用,因此应该清理。

GC 的行为方式也可能取决于硬件,即如果系统有大量可用内存,它的工作方式可能与没有时不同。

我有一个加载了超过 3000 条记录的应用程序,控制器对每个活动都有一个引用,因此列表视图的适配器中的数据没有被清理。

至于开销,这不一定是 GC - 但看起来它会导致开销。唯一的其他影响因素是在屏幕上渲染组件所花费的时间等。

希望有帮助!

~ 丹

于 2013-01-30T03:24:29.873 回答