Android:为什么开始新活动需要这么长时间?

时间:2013-01-30 02:56:48

标签: android performance android-activity

我有一个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提供的信息记录了内存可用性。

1 个答案:

答案 0 :(得分:1)

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

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

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

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

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

希望有所帮助!

〜丹