Android Memory Usage Problem on possibly using ActivityGroup
This is a little bit long story that i ended up messing with memory problems. I developed very deep android application by using very amount of Activities and Frameworks. First of all I have to say I used ActivityGroups for main categories to handle activities easily. And I can achieve all activities via getLocalActivityManager()
. And I get this error message:
02-25 11:34:13.749:
ERROR/dalvikvm-heap(3042):
2764800-byte external allocation too
large for this process.
02-25 11:34:13.749:
ERROR/GraphicsJNI(3042): VM won't let
us allocate 2764800 bytes
then my application will crash with various exceptions, eg;
02-25 11:34:13.772: ERROR/AndroidRuntime(3042): FATAL EXCEPTION: main
02-25 11:34:13.772: ERROR/AndroidRuntime(3042): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.turkcell.seyahat/com.matriksdata.ui.schedule.MessageDetail}: android.view.InflateException: Binary XML file line #2: Error inflating class <unknown>
02-25 11:34:13.772: ERROR/AndroidRuntime(3042): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2663)
02-25 11:34:13.772: ERROR/AndroidRuntime(3042): at android.app.ActivityThread.startActivityNow(ActivityThread.java:2503)
02-25 11:34:13.772: ERROR/AndroidRuntime(3042): at android.app.LocalActivityManager.moveToState(LocalActivityManager.java:127)
02-25 11:34:13.772: ERROR/AndroidRuntime(3042): at android.app.LocalActivityManager.startActivity(LocalActivityManager.java:339)
02-25 11:34:13.772: ERROR/AndroidRuntime(3042): at com.matriksdata.app.XActivityGroup.goForward(XActivityGroup.java:122)
02-25 11:34:13.772: ERROR/AndroidRuntime(3042): at com.matriksdata.ui.parents.ScheduleActivityGroup.goForward(ScheduleActivityGroup.java:143)
02-25 11:34:13.772: ERROR/AndroidRuntime(3042): at com.matriksdata.ui.schedule.MessageBox.onItemClick(MessageBox.java:81)
02-25 11:34:13.772: ERROR/AndroidRuntime(3042): at android.widget.AdapterView.performItemClick(AdapterView.java:284)
02-25 11:34:13.772: ERROR/AndroidRuntime(3042): at android.widget.ListView.performItemClick(ListView.java:3730)
02-25 11:34:13.772: ERROR/AndroidRuntime(3042): at android.widget.AbsListView$PerformClick.run(AbsListView.java:1808)
02-25 11:34:13.772: ERROR/AndroidRuntime(3042): at android.os.Handler.handleCallback(Handler.java:587)
02-25 11:34:13.772: ERROR/AndroidRuntime(3042): at android.os.Handler.dispatchMessage(Handler.java:92)
02-25 11:34:13.772: ERROR/AndroidRuntime(3042): at android.os.Looper.loop(Looper.java:123)
02-25 11:34:13.772: ERROR/AndroidRuntime(3042): at android.app.ActivityThread.main(ActivityThread.java:4627)
02-25 11:34:13.772: ERROR/AndroidRuntime(3042): at java.lang.reflect.Method.invokeNative(Native Method)
02-25 11:34:13.772: ERROR/AndroidRuntime(3042): at java.lang.reflect.Method.invoke(Method.java:521)
02-25 11:34:13.772: ERROR/AndroidRuntime(3042): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:871)
02-25 11:34:13.772: ERROR/AndroidRuntime(3042): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:629)
02-25 11:34:13.772: ERROR/AndroidRuntime(3042): at dalvik.system.NativeStart.main(Native Method)
02-25 11:34:13.772: ERROR/AndroidRuntime(3042): Caused by: android.view.InflateException: Binary XML file line #2: Error inflating class <unknown>
02-25 11:34:13.772: ERROR/AndroidRuntime(3042): at android.view.LayoutInflater.createView(LayoutInflater.java:513)
02-25 11:34:13.772: ERROR/AndroidRuntime(3042): at com.android.internal.policy.impl.PhoneLayoutInflater.onCreateView(PhoneLayoutInflater.java:56)
02-25 11:34:13.772: ERROR/AndroidRuntime(3042): at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:563)
02-25 11:34:13.772: ERROR/AndroidRuntime(3042): at android.view.LayoutInflater.inflate(LayoutInflater.java:385)
02-25 11:34:13.772: ERROR/AndroidRuntime(3042): at android.view.LayoutInflater.inflate(LayoutInflater.java:320)
02-25 11:34:13.772: ERROR/AndroidRuntime(3042): at android.view.LayoutInflater.inflate(LayoutInflater.java:276)
02-25 11:34:13.772: ERROR/AndroidRuntime(3042): at com.android.internal.policy.impl.PhoneWindow.setContentView(PhoneWindow.java:210)
02-25 11:34:13.772: ERROR/AndroidRuntime(3042): at android.app.Activity.setContentView(Activity.java:1647)
02-25 11:34:13.772: ERROR/AndroidRuntime(3042): at com.matriksdata.ui.schedule.MessageDetail.onCreate(MessageDetail.java:33)
02-25 11:34:13.772: ERROR/AndroidRuntime(3042): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)
02-25 11:34:13.772: ERROR/AndroidRuntime(3042): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2627)
02-25 11:34:13.772: ERROR/AndroidRuntime(3042): ... 18 more
02-25 11:34:13.772: ERROR/AndroidRuntime(3042): Caused by: java.lang.reflect.InvocationTargetException
02-25 11:34:13.772: ERROR/AndroidRuntime(3042): at android.widget.LinearLayout.<init>(LinearLayout.java:115)
02-25 11:34:13.772: ERROR/AndroidRuntime(3042): at java.lang.reflect.Constructor.constructNative(Native Method)
02-25 11:34:13.772: ERROR/AndroidRuntime(3042): at java.lang.reflect.Constructor.newInstance(Constructor.java:446)
02-25 11:34:13.772: ERROR/AndroidRuntime(3042): at android.view.LayoutInflater.createView(LayoutInflater.java:500)
02-25 11:34:13.772: ERROR/AndroidRuntime(3042): ... 28 more
02-25 11:34:13.772: ERROR/AndroidRuntime(3042): Caused by: java.lang.OutOfMemoryError: bitmap size exceeds VM budget
02-25 11:34:13.772: ERROR/AndroidRuntime(3042): at android.graphics.Bitmap.nativeCreate(Native Method)
02-25 11:34:13.772: ERROR/AndroidRuntime(3042): at android.graphics.Bitmap.createBitmap(Bitmap.java:468)
02-25 11:34:13.772: ERROR/AndroidRuntime(3042): at android.graphics.Bitmap.createBitmap(Bitmap.java:435)
02-25 11:34:13.772: ERROR/AndroidRuntime(3042): at android.graphics.Bitmap.createScaledBitmap(Bitmap.java:340)
02-25 11:34:13.772: ERROR/AndroidRuntime(3042): at android.graphics.BitmapFactory.finishDecode(BitmapFactory.java:590)
02-25 11:34:13.772: ERROR/AndroidRuntime(3042): at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:564)
02-25 11:34:13.772: ERROR/AndroidRuntime(3042): at android.graphics.BitmapFactory.decodeResourceStream(BitmapFactory.java:425)
02-25 11:34:13.772: ERROR/AndroidRuntime(3042): at android.graphics.drawable.Drawable.createFromResourceStream(Drawable.java:697)
02-25 11:34:13.772: ERROR/AndroidRuntime(3042): at android.content.res.Resources.loadDrawable(Resources.java:1709)
02-25 11:34:13.772: ERROR/AndroidRuntime(3042): at android.content.res.TypedArray.getDrawable(TypedArray.java:601)
02-25 11:34:13.772: ERROR/AndroidRuntime(3042): at android.view.View.<init>(View.java:1885)
02-25 11:34:13.772: ERROR/AndroidRuntime(3042): at android.view.View.<init>(View.java:1834)
02-25 11:34:13.772: ERROR/AndroidRuntime(3042): at android.view.ViewGroup.<init>(ViewGroup.java:285)
02-25 11:34:13.772: ERROR/AndroidRuntime(3042): ... 32 more
Of course i don’t have 2764800 byte png image, but i think its decoded size. So i thought that i had image handling problems and i checked and fixed my project in every detail to handle images correctly. I checked everything described in android-developers.blogspot.com/2009/01/avoiding-memory-leaks.html . I checked null drawables, i follow model reusability instructions, i changed loading methods described in : stackoverflow.com/questions/477572/android-strange-out-of-memory-issue/823966#823966.
Also i have few bitmaps to load from disk. My all layouts created by android xml layout files. I have plenty of bitmaps described in xml files also.
Then i saw that i have big static classes in application with memory analyzer. i freed that static properties by loading on demand and freeing after used. So finally i got this memory leak suspects in MAT;
Problem Suspect 1
3,043 instances of "java.lang.Class", loaded by "" occupy 871,304 (17.97%) bytes.
Biggest instances:
class com.ibm.icu4jni.util.Resources$DefaultTimeZones @ 0x4014c3b0 - 166,768 (3.44%) bytes.
class android.text.Html$HtmlParser @ 0x400fe448 - 126,592 (2.61%) bytes.
class com.google.googlenav.proto.GmmMessageTypes @ 0x4835d450 - 56,944 (1.17%) bytes.
class org.apache.harmony.luni.internal.net.www.protocol.http.HttpConnectionPool @ 0x47caea20 - 51,872 (1.07%) bytes.
class org.apache.harmony.security.fortress.Services @ 0x4008c4d0 - 51,456 (1.06%) bytes.
Problem Suspect 2
8,721 instances of 'java.lang.String', loaded by 'system class loader' occupy 549,624 (11.33%) bytes. Keywords java.lang.String
Problem Suspect 3
60 instances of "org.bouncycastle.jce.provider.X509CertificateObject", loaded by "system class loader" occupy 300,024 (10.76%) bytes. These instances are referenced from one instance of "java.util.Hashtable$HashtableEntry[]", loaded by "system class loader" Keywords org.bouncycastle.jce.provider.X509CertificateObject java.util.Hashtable$HashtableEntry[]
This third one not occurs every time. Generally when i use memory manager in GalaxyTab.
My biggest Top-level Dominator Classes are these. http://www.matriks.mobi/arge/android/Screen%20shot%202011-02-25%20at%2012.19.08%20PM.png
I have just 2 or 3 activities live and the rest of them are suspended. I get this messages in components report. Of course this is not the explanation that i use just 1.5 MB of ram, because according to memory manager my application uses 48 MB of ram up from about 20 MB.
Possible Memory Waste * Duplicate Strings* Found 0 occurrences of char[] with at least 10 instances having identical content. Total size is 0 bytes.
i think thats not the thing that i want :) hprof file located in http://www.matriks.mobi/arge/android/android5706014442078310727.hprof.zip
I am guessing that i have problem with ActivityGroup class. At least i am keeping activities and activity ids in LocalActivityManager in stacks. But even if i don’t create new activities, and passing between loaded ones, memory increases.
I know this is not the way of searching for leaks, and possibly i have a code based problem causing this memory leaks. But any single idea that i should check will be very very welcome here, because i am kinda stuck here.
Do you use this layout for the rows of a ListView?
I was resetting background image everytime activitygroup created by;
I removed this and left the description in xml, so problem solved. This method causes memory leaks.
Try tracking memory allocations while application is in use.
Also, holding references to Bitmap Drawables can produce memory leaks. When a Drawable is added to View, a circular reference is created. So when you hold a reference to Bitmap drawable, it further holds a reference to a View and this View can never be GCed.
The easiest way to avoid it is to extract a bitmap from a Bitmap Drawable and hold a reference to it, then when Activity is restarted/reloaded, you create new Bitmap Drawables from this bitmaps. This is how a Photostream example works (described at the end): Faster screen orientation change