Reputation: 3103
I have an Android activity BrowseActivity
which load about 3000 records (@ about 100 bytes) from database into memory and show them in a ListView
. It takes about 3 to 6 seconds in AVD to load, which is fine.
The problem arises when I want to start a new activity from within this BrowseActivity
. It takes about 30 seconds, even just to open the most trivial activity. Dalvik VM seems to do a LOT of garbage collecting for unknown reason. Please check logcat
output below.
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
I already experimented with lower number of records: 1 and 300. It results in a much fewer garbage collection messages (1 and 7, respectively) and a much faster activity load (1 and 6 seconds, respectively), but the memory availability difference is quite trivial:
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
It seems that the slow activity load time is caused by GC overheads. My question is: Why does Dalvik VM does a lot of GC? Even with 3000 records, I believe it would only take top 500 KB in memory. If it's not about GC overheads, what's the other possible causes for this slow activity load?
For the record, I logged the memory availability using the information provided by built-in class ActivityManager.MemoryInfo.
Upvotes: 3
Views: 1663
Reputation: 5963
I don't think you have a reference to the Activity with 3000 records in it, and that is causing the GC to be activated when you change activities.
If you use a MVC type pattern and have a controller with a reference to each Activity I don't think the GC will clean up those records. The GC kicks in when a section of memory exists but there is no known reference to it, once you switch activities the reference to the activity and all its function and member variables are no longer used and thus should be cleaned up.
The way the GC behaves may also depend on hardware, i.e. if the system has a lot of memory available it may work different to when there is not.
I have an app with much more than 3000 records loaded, the Controller has a reference to each activity and thus the data in the adapters for list views are not cleaned up.
As for the overheads, this isn't necessarily GC - but it looks like it would be contributing to the overhead. The only other contributing factor would be the time taken to render components on the screen etc.
Hope that helps!
~ Dan
Upvotes: 1