Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android: unparceling causes out of memory exception. How to inspect objects?

Here's the setup:

  • I have an activity with a list of items (updated from server, represented by a plain java class). The items are rendered via a custom BaseAdapter and custom View for each row.
  • The items implement Parcelable, so that when the screen is rotated, the items are saved in the bundle as a ParcelableArrayList, then restored without going back to the server.

So far, this is a fairly straightforward setup, however I want to pass one of these items to another activity. Bundle has a "pubExtra(String, Parcelable)" method, which I wanted to use to put the object there, then pass via the intent. When I did this, the device started getting a force close due to an OutOfMemoryException. It seems when trying to unparcel the object, it requests ~30mb(!)

It seems like the object must be holding references to something else, since the object itself only contains a few int/float/String fields and related methods. I haven't been able to track this down by looking at the code or debug inspector and I don't know how to use the Heap viewer effectively.

Any suggestions?

Here's the stacktrace

/dalvikvm-heap( 5876): Out of memory on a 29098436-byte allocation.
I/dalvikvm( 5876): "main" prio=5 tid=1 RUNNABLE
I/dalvikvm( 5876):   | group="main" sCount=0 dsCount=0 s=N obj=0x4001d8d0 self=0xccc8
I/dalvikvm( 5876):   | sysTid=5876 nice=0 sched=0/0 cgrp=default handle=-1345017816
I/dalvikvm( 5876):   | schedstat=( 1107116708 1124999998 2626 )
I/dalvikvm( 5876):   at java.util.ArrayList.<init>(ArrayList.java:~84)
I/dalvikvm( 5876):   at android.os.Parcel.readArrayList(Parcel.java:1460)
I/dalvikvm( 5876):   at android.os.Parcel.readValue(Parcel.java:1792)
I/dalvikvm( 5876):   at android.os.Parcel.readMapInternal(Parcel.java:2007)
I/dalvikvm( 5876):   at android.os.Bundle.unparcel(Bundle.java:208)
I/dalvikvm( 5876):   at android.os.Bundle.containsKey(Bundle.java:249)
I/dalvikvm( 5876):   at <mypackage>.BaseDetailsActivity.isInModifyState(BaseDetailsActivity.java:184)
I/dalvikvm( 5876):   at <mypackage>.DetailsActivity.onCreate(DetailsActivity.java:230)
I/dalvikvm( 5876):   at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)
I/dalvikvm( 5876):   at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2627)
I/dalvikvm( 5876):   at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2679)
I/dalvikvm( 5876):   at android.app.ActivityThread.access$2300(ActivityThread.java:125)
I/dalvikvm( 5876):   at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2033)
I/dalvikvm( 5876):   at android.os.Handler.dispatchMessage(Handler.java:99)
I/dalvikvm( 5876):   at android.os.Looper.loop(Looper.java:123)
I/dalvikvm( 5876):   at android.app.ActivityThread.main(ActivityThread.java:4627)
I/dalvikvm( 5876):   at java.lang.reflect.Method.invokeNative(Native Method)
I/dalvikvm( 5876):   at java.lang.reflect.Method.invoke(Method.java:521)
I/dalvikvm( 5876):   at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868)
I/dalvikvm( 5876):   at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626)
I/dalvikvm( 5876):   at dalvik.system.NativeStart.main(Native Method)
like image 430
Martin Avatar asked Oct 22 '10 16:10

Martin


2 Answers

I had the same problem that boiled down to this: I slipped up and one of my variables wasn't being written in the correct sequence. I think Parcelable works on a very low level.

My guess is that on the low level, it tried to read an arraylist at the wrong memory location, and it never got the "Stop reading!" signal. So, it kept reading like crazy until the Heap Space hit the app limit. *I'm also guessing that you probably had/are having a similar issue

Bottom line: double-check your Parcelable reading and writing functions and make sure they are reading/writing the variables in the same sequence

  • Even though this was asked a pretty long time ago. I found this page via Google so went ahead and posted this in case anyone else out there got the same problem.

Edit: I would recommend elevine's suggestion as well and I encourage voting it up. This actually helped me narrow it down to ArrayLists in the Parcel object

like image 119
Joe Plante Avatar answered Oct 04 '22 21:10

Joe Plante


You should try using the Eclipse Memory Analyzer Tool . Install it as a plugin to Eclipse, and then use the "Dump Hprof file" button in DDMS (looks like a green cylinder with a down arrow on the Devices tab"). With MAT installed, Eclipse should just launch it with some views to inspect your memory.

If you post some of your code, someone might be able to find the problem too.

like image 45
Eric Levine Avatar answered Oct 04 '22 22:10

Eric Levine