I'm trying to explore the behavior of the new concurrent garbage collector in GingerBread (2.3).
Could someone please explain these example log lines in details (especially the "paused" parts of GC_CONCURRENT and GC_FOR_MALLOC)?
12-24 10:20:54.912 D/dalvikvm( 414): GC_CONCURRENT freed 510K, 57% free 2529K/5831K, external 716K/1038K, paused 8ms+5ms
12-24 10:20:54.963 D/dalvikvm( 414): GC_FOR_MALLOC freed 510K, 57% free 2529K/5831K, external 716K/1038K, paused 47ms
GC_CONCURRENT Heap is (almost) full. Therefore concurrent GC kicks in
freed 510K - Amount of memory freed
57% free - Memory after freeing %
2529K/5831K - Actual mem in heap
external 716K/1038K - Externally allocated memory (memory that is not in dvm)
paused 8ms+5ms - time taken for GC
especially the "paused" parts
For concurrent collections there are two pause times. One is at the beginning of the collection and other towards the end. For non-concurrent collection there will be only one pause time.
if you haven't yet, check out this video:
http://www.google.com/events/io/2011/sessions/memory-management-for-android-apps.html
Related
I'm in the final stages of implementing a game for the Android platform and have been doing some memory profiling over the past few days. Although the app is running fine within the emulator environment, I am curious to know whether the memory it's using falls within an acceptable range.
While the app has been running, I've captured lines containing details such as the following in the output window:
GC_EXTERNAL_ALLOC freed 14K, 50% free 2939K/5831K, external 2210K/2581K, paused 170ms
GC_EXTERNAL_ALLOC freed 104K, 47% free 3142K/5895K, external 3710K/4633K, paused 263ms
GC_EXTERNAL_ALLOC freed 17K, 48% free 3106K/5895K, external 6362K/6398K, paused 104ms
GC_CONCURRENT freed 98K, 46% free 3225K/5959K, external 7462K/8042K, paused 8ms+8ms
GC_EXTERNAL_ALLOC freed 172K, 47% free 3269K/6087K, external 8023K/8042K, paused 183ms
As you can see, it typically runs with about 48% free memory.
My question is basically whether this is an acceptable amount of free memory?
Thanks,
Wayne.
What does these numbers mean below? (caught with LogCat debugger)
08-03 14:29:11.538: I/dalvikvm-heap(6514): Forcing collection of SoftReferences for 14337016-byte allocation
08-03 14:29:11.568: D/dalvikvm(6514): GC_BEFORE_OOM freed 10K, 6% free 115756K/121948K, paused 29ms, total 30ms
08-03 14:29:11.568: E/dalvikvm-heap(6514): Out of memory on a 14337016-byte allocation.
What does 121948K and 115756K mean?
Why 14337016 byte? It is ~14MB. It's impossible! I tried to load a bitmap with 14kB size.
system is trying to free unused memory in order to be able to find some more resources for your application
GC_BEFORE_OOM happens your app's running out of its heap space
more about GC_BEFORE_OOM can be found here
Numbers:
gc freed 10K, 6% is free, which is too little, so it continues deallocation further until gc reaches oom. 115756K/121948K is statistics of the heap of your application
more information about the memory can be found by watching this vid
When I run my application on emulator the Logcat is showing this:
04-22 16:21:30.685: D/dalvikvm(967): GC_CONCURRENT freed 1545K, 20% free 7019K/8720K, paused 78ms+17ms, total 360ms
04-22 16:21:30.685: D/dalvikvm(967): WAIT_FOR_CONCURRENT_GC blocked 143ms
04-22 16:21:31.845: D/dalvikvm(967): GC_CONCURRENT freed 1552K, 20% free 7019K/8720K, paused 116ms+18ms, total 554ms
04-22 16:21:31.845: D/dalvikvm(967): WAIT_FOR_CONCURRENT_GC blocked 268ms
04-22 16:21:32.435: D/dalvikvm(967): GC_CONCURRENT freed 1545K, 20% free 7019K/8720K, paused 75ms+9ms, total 192ms
04-22 16:21:32.435: D/dalvikvm(967): WAIT_FOR_CONCURRENT_GC blocked 73ms
04-22 16:21:32.945: D/dalvikvm(967): GC_CONCURRENT freed 1552K, 20% free 7019K/8720K, paused 75ms+10ms, total 209ms
04-22 16:21:32.945: D/dalvikvm(967): WAIT_FOR_CONCURRENT_GC blocked 70ms
04-22 16:21:33.434: D/dalvikvm(967): GC_CONCURRENT freed 1545K, 20% free 7019K/8720K, paused 78ms+12ms, total 192ms
and this continues until I exit the application.Any suggestion?Thanks
Seems like you're creating many new objects and throw them away soon.
For WAIT_FOR_CONCURRENT_GC see this one:
what does WAIT_FOR_CONCURRENT_GC blocked mean?
It means you try to allocate memory (for example object creation) and it doesn't fit into memory. Thats what GC_CONCURRENT freed is caused by. Its just usual garbage collection.
If you've got performance problems, try to reuse objects or spare them.
This means you are doing too many operations and a lot of memory is being used. Hence, GC(Garbage collector) is being called to free up memory.
04-22 16:21:30.685: D/dalvikvm(967): GC_CONCURRENT freed 1545K, 20%
free 7019K/8720K, paused 78ms+17ms, total 360ms
freed indicates how much memory was freed
GC_CONCURRENT Invoked when the heap gets too large to prevent overflow.
paused 78ms+17ms – indicates how much time it took the GC to finish collection.
Refer
Additionally take memory dump and analyze the dump use MAT tool.
Agree mostly with #luxer, but I believe it's not that you are allocating too many objects, but you are allocating some huge objects. If you refer to the link pointed by #luxer about WAIT_FOR_CONCURRENT_GC, you will realize that a second gc is being triggered in your app while a concurrent gc (which is typically triggered when the heap occupancy hits a soft limit) is in progress. The second gc could have been triggered by you explicitly or because an allocation failed. Since you have not indicated that you're calling System.gc(), I would assume that your allocations are failing and the system is trying to do a gc.
So, yeah, you should seriously consider reusing some huge objects instead of allocating them each time. This is a better practice, but if for some reason you're unable to do that, you can probably bump your heap size (by setting large heap) and that may help.
Sometimes it happens when you have a never ending loop just because some condition is always true.
Try to figure out if its this case first as it happens mostly because of this.
I was able to resolve mine by debugging my code : There was a DB operation lurking in an infinite while loop, which was filling the bean and hence causing the memory leak.
Maybe if you'r a a newbie like me, please check on the while/do-while/for loops and object allocations done in loops.
Un closed connections and Cursors should also be closed.
Thanks,
I connect my android phone to eclipse. And I see these message from Logcat.
Can you please tell me what does is the difference between 'GC_EXPLICIT' and 'GC_EXTERNAL_ALLOC'? and what does "45% free" mean?
10-05 12:08:34.450: DEBUG/dalvikvm(813): GC_EXTERNAL_ALLOC freed 63K, 45% free 3156K/5703K, external 4113K/4348K, paused 73ms
10-05 12:08:34.480: DEBUG/dalvikvm(101): GC_EXTERNAL_ALLOC freed 55K, 40% free 5883K/9799K, external 4911K/4913K, paused 124ms
10-05 12:08:37.120: DEBUG/dalvikvm(101): GC_EXPLICIT freed 84K, 41% free 5870K/9799K, external 5745K/6078K, paused 104ms
10-05 12:08:40.099: DEBUG/dalvikvm(493): GC_EXPLICIT freed 14K, 48% free 3782K/7175K, external 1625K/2137K, paused 75ms
10-05 12:08:45.110: DEBUG/dalvikvm(188): GC_EXPLICIT freed 57K, 54% free 3203K/6855K, external 4988K/6206K, paused 78ms
10-05 12:09:05.119: DEBUG/dalvikvm(822): GC_EXPLICIT freed 349K, 46% free 3696K/6727K, external 1625K/2137K, paused 65ms
I would highly suggest giving the Memory Management video presentation from Google I/O 2011 a watch:
http://www.youtube.com/watch?v=_CruQY55HOk
At about 14 minutes in, he goes in to depth on exactly what these mean in the logcat output.
GC Explicit basically means that an app has explicitly called System.gc();
GC Concurrent is triggered when your heap starts to fill up and a Concurrent GC kicks in to hopefully clear memory before it fills up.
GC_EXPLICIT means your app has explicitly called System.gc() or the Activity Manger of Android System called System.gc()
GC_EXTERNAL_ALLOC is something more complicated.
There are some memory related to the life time of Java's object called EXTERNAL memory. Such as memory use by GPU or pixmap resources of your app. This type of memory allocating use "malloc" of stdlib to allocation heap memory but NOT allocating from the GC Heap of Dalvik, but it's also one of the "HEAP" memory. And the total size use of the HEAP must be smaller than a limit(decide by GC).
Dalvik tracking allocation of that memory.
CONDITION: usableof(GC_HEAP) + usableof(NATIVE_HEAP[external]) <= allocaionLimit
Dalvik will cause a GC for GC_EXTERNAL_ALLOC as a sideeffect when the condition above is not true.
Good day all, i have a load of images i want to display from an sdcard to a gridview. I have followed the tutorial to do this in the is link:
http://mihaifonoage.blogspot.com/2009/11/displaying-images-from-sd-card-in.html
everything works great apart the fact that when the images become a lot, it becomes really slow to populate it and scrolling is also very slow. i have tried editing the code to use the ViewHolder method but still no luck.
now, i also have used populated the images in a custom ListView without using the AsyncTask and it appears to process it faster. yeah common sense would be to just use the faster method but want to clarify somethings first. so i am asking:
is it that AsyncTask can be really slow in some cases and not ideal or thus the fact that am using a Gridview or Listview have something to do with it? any reason why? am asking this cause AsyncTask always seem to get very good favourism.
Any Other way, solutions or tips that i can make this process faster?..
Note: i would have posted my code, but its the same things as the link only that i don't use the getThumbnails() in the MediaStore query. Thanks in advance.
here is part what i get for the logcat output when its loading the images:
10-07 19:42:54.072: DEBUG/dalvikvm(20291): GC_EXPLICIT freed <1K, 48% free 2886K/5511K, external 1574K/14018K, paused 28ms
10-07 19:42:54.092: DEBUG/dalvikvm(20291): GC_EXPLICIT freed <1K, 48% free 2918K/5511K, external 1574K/14018K, paused 25ms
10-07 19:42:54.122: DEBUG/dalvikvm(20291): GC_EXPLICIT freed <1K, 48% free 2918K/5511K, external 1574K/14018K, paused 25ms
10-07 19:42:54.142: DEBUG/dalvikvm(20291): GC_EXPLICIT freed <1K, 48% free 2918K/5511K, external 1574K/14018K, paused 24ms
10-07 19:42:54.172: DEBUG/dalvikvm(20291): GC_EXPLICIT freed <1K, 48% free 2918K/5511K, external 1574K/14018K, paused 25ms
10-07 19:42:54.202: DEBUG/dalvikvm(20291): GC_EXPLICIT freed <1K, 48% free 2918K/5511K, external 1574K/14018K, paused 25ms
10-07 19:42:54.232: DEBUG/dalvikvm(20291): GC_EXPLICIT freed <1K, 48% free 2918K/5511K, external 14018K/14018K, paused 28ms
10-07 19:42:54.252: DEBUG/dalvikvm(20291): GC_EXPLICIT freed <1K, 48% free 2918K/5511K, external 14018K/14018K, paused 24ms
10-07 19:42:54.282: DEBUG/dalvikvm(20291): GC_EXPLICIT freed <1K, 48% free 2918K/5511K, external 14018K/14018K, paused 24ms
10-07 19:42:54.302: DEBUG/dalvikvm(20291): GC_EXPLICIT freed <1K, 48% free 2918K/5511K, external 14018K/14018K, paused 25ms
10-07 19:42:54.332: DEBUG/dalvikvm(20291): GC_EXPLICIT freed <1K, 48% free 2918K/5511K, external 14018K/14018K, paused 25ms
10-07 19:42:54.362: DEBUG/dalvikvm(20291): GC_EXPLICIT freed <1K, 48% free 2918K/5511K, external 14018K/14018K, paused 25ms
It is slow because in fact you are still using one single thread (i.e. one AsyncTask.execute() call) download all images in sequence (i.e. loop all image download in your doInBackground() implementation). Yes, this is the way that google suggested how to use AsyncTask.
By calling several AsyncTask.execute() will probably speed you up, this gives you several thread running simultaneously and managed by underlying thread pool (before API level 11, this thread pool is non accessible). of cause, you need somehow split your download task into several piece and feed each piece into each AsyncTask.execute():
for (DownloadTask task : tasks) {
new AsyncTask.execute();
}
Check out here for more information.
The right way to speed this up would be to use a image cache. Google has a guide for an easy implementation right here: