Android: разбор неполадок вызывает нехватку памяти. Как осматривать объекты? - PullRequest
5 голосов
/ 22 октября 2010

Вот настройка:

  • У меня есть действие со списком элементов (обновленных с сервера, представленных простым классом Java).Элементы визуализируются с помощью настраиваемого BaseAdapter и настраиваемого представления для каждой строки.
  • Элементы реализуют Parcelable, поэтому при повороте экрана элементы сохраняются в комплекте как ParcelableArrayList, а затем восстанавливаются без возвратана сервер.

Пока это довольно простая установка, однако я хочу передать один из этих элементов другому действию.В Bundle есть метод pubExtra (String, Parcelable), который я хотел использовать, чтобы поместить туда объект, а затем передать его через намерение.Когда я сделал это, устройство начало закрываться силой из-за исключения OutOfMemoryException.Кажется, что при попытке разархивировать объект, он запрашивает ~ 30 МБ (!)

Кажется, что объект должен содержать ссылки на что-то еще, так как сам объект содержит только несколько полей int / float / String исвязанные методы.Я не смог отследить это, глядя на код или инспектор отладки, и я не знаю, как эффективно использовать средство просмотра кучи.

Есть предложения?

Вот трассировка стека

/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)

Ответы [ 2 ]

14 голосов
/ 13 июля 2012

У меня была та же проблема, которая сводилась к следующему: я поскользнулся, и одна из моих переменных не была записана в правильной последовательности. Я думаю, что Parcelable работает на очень низком уровне.

Я предполагаю, что на низком уровне он пытался прочитать arraylist в неправильном месте памяти, и он никогда не получал "Прекратить чтение!" сигнал. Таким образом, он продолжал читать как сумасшедший, пока пространство кучи не достигло предела приложения. * Я также предполагаю, что у вас, вероятно, была / есть похожая проблема

Итог: перепроверьте свои функции чтения и записи Parcelable и убедитесь, что они читают / записывают переменные в той же последовательности

  • Хотя об этом спрашивали довольно давно. Я нашел эту страницу через Google, поэтому продолжил и разместил ее на тот случай, если кто-нибудь еще столкнется с такой же проблемой.

Редактировать: Я бы также порекомендовал предложение Эвин, и я рекомендую проголосовать за него. Это фактически помогло мне сузить его до ArrayLists в объекте Parcel

5 голосов
/ 22 октября 2010

Вам следует попробовать использовать Eclipse Memory Analyzer Tool . Установите его как плагин для Eclipse, а затем используйте кнопку «Dump Hprof file» в DDMS (выглядит как зеленый цилиндр со стрелкой вниз на вкладке «Устройства»). После установки MAT Eclipse должен просто запустить его с некоторыми представлениями проверить вашу память.

Если вы разместите часть своего кода, кто-то может найти проблему тоже.

...