2010-09-29 3 views
7

У меня есть приложение, которое имеет функцию показа POI на карте. Это только одна POI, и она отображается только тогда, когда она действительно находится в видимой области экрана. Он работает отлично на некоторое время, но если я буду играть в масштабирование, вытащить и перетащить, он в конечном итоге потерпит крах. Согласно Logcat, причиной всегда является ошибка OutOfMemory.Ошибка памяти при использовании API Карт Google

Сначала я подумал, что это ошибка в API Карт Google. После некоторого исследования и просмотра некоторых записей Romain Guy я был уверен в том, что я сделал что-то глупое в своем приложении, которое время от времени не хватало памяти. Затем я провел более подробные тесты с помощью анализатора кучи (Eclipse), и я увидел, что, хотя у меня было 2+, иногда 3+ мегабайта от свободной памяти, я все еще получал эти раздражающие сообщения Force Close, вызванные OutOfMemoryError. В большинстве случаев он сбой при попытке выделить часть памяти объемом 614 КБ независимо от того, сколько у меня осталось.

Эта проблема часто встречается на Nexus One 2.2.1 и на HTC Evo 2.1. После небольшого тестирования я не получил ни одного сбоя ни на G1 1.6, ни на Samsung Galaxy S i9000 2.1. Но я не могу сказать точно, что G1 и Galaxy не будут показывать эту проблему после более тщательного тестирования.

Я могу думать только о проблеме фрагментации памяти. Надеюсь, у этой проблемы есть решение. Я также буду рад, если я смогу просто поймать эту ошибку и предотвратить приложение от сбоев.

Если это помогает, вот LogCat:

09-29 08:58:06.661: ERROR/dalvikvm-heap(1552): 648000-byte external allocation too large for this process. 
09-29 08:58:06.661: ERROR/dalvikvm(1552): Out of memory: Heap Size=9991KB, Allocated=6980KB, Bitmap Size=14510KB 
09-29 08:58:06.661: ERROR/(1552): VM won't let us allocate 648000 bytes 
09-29 08:58:06.672: DEBUG/AndroidRuntime(1552): Shutting down VM 
09-29 08:58:06.672: WARN/dalvikvm(1552): threadid=3: thread exiting with uncaught exception (group=0x4001b390) 
09-29 08:58:06.672: ERROR/AndroidRuntime(1552): Uncaught handler: thread main exiting due to uncaught exception 
09-29 08:58:06.681: ERROR/AndroidRuntime(1552): java.lang.OutOfMemoryError: bitmap size exceeds VM budget 
09-29 08:58:06.681: ERROR/AndroidRuntime(1552):  at android.graphics.Bitmap.nativeCreate(Native Method) 
09-29 08:58:06.681: ERROR/AndroidRuntime(1552):  at android.graphics.Bitmap.createBitmap(Bitmap.java:569) 
09-29 08:58:06.681: ERROR/AndroidRuntime(1552):  at com.google.android.maps.ZoomHelper.createSnapshot(ZoomHelper.java:422) 
09-29 08:58:06.681: ERROR/AndroidRuntime(1552):  at com.google.android.maps.ZoomHelper.beginZoom(ZoomHelper.java:186) 
09-29 08:58:06.681: ERROR/AndroidRuntime(1552):  at com.google.android.maps.MapView$2.onScaleBegin(MapView.java:371) 
09-29 08:58:06.681: ERROR/AndroidRuntime(1552):  at android.view.ScaleGestureDetector.onTouchEvent(ScaleGestureDetector.java:208) 
09-29 08:58:06.681: ERROR/AndroidRuntime(1552):  at com.google.android.maps.MapView.onTouchEvent(MapView.java:646) 
09-29 08:58:06.681: ERROR/AndroidRuntime(1552):  at android.view.View.dispatchTouchEvent(View.java:3709) 
09-29 08:58:06.681: ERROR/AndroidRuntime(1552):  at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:874) 
09-29 08:58:06.681: ERROR/AndroidRuntime(1552):  at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:924) 
09-29 08:58:06.681: ERROR/AndroidRuntime(1552):  at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:924) 
09-29 08:58:06.681: ERROR/AndroidRuntime(1552):  at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:924) 
09-29 08:58:06.681: ERROR/AndroidRuntime(1552):  at com.android.internal.policy.impl.PhoneWindow$DecorView.superDispatchTouchEvent(PhoneWindow.java:1701) 
09-29 08:58:06.681: ERROR/AndroidRuntime(1552):  at com.android.internal.policy.impl.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1116) 
09-29 08:58:06.681: ERROR/AndroidRuntime(1552):  at android.app.Activity.dispatchTouchEvent(Activity.java:2068) 
09-29 08:58:06.681: ERROR/AndroidRuntime(1552):  at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchTouchEvent(PhoneWindow.java:1685) 
09-29 08:58:06.681: ERROR/AndroidRuntime(1552):  at android.view.ViewRoot.handleMessage(ViewRoot.java:1708) 
09-29 08:58:06.681: ERROR/AndroidRuntime(1552):  at android.os.Handler.dispatchMessage(Handler.java:99) 
09-29 08:58:06.681: ERROR/AndroidRuntime(1552):  at android.os.Looper.loop(Looper.java:123) 
09-29 08:58:06.681: ERROR/AndroidRuntime(1552):  at android.app.ActivityThread.main(ActivityThread.java:4595) 
09-29 08:58:06.681: ERROR/AndroidRuntime(1552):  at java.lang.reflect.Method.invokeNative(Native Method) 
09-29 08:58:06.681: ERROR/AndroidRuntime(1552):  at java.lang.reflect.Method.invoke(Method.java:521) 
09-29 08:58:06.681: ERROR/AndroidRuntime(1552):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:860) 
09-29 08:58:06.681: ERROR/AndroidRuntime(1552):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:618) 
09-29 08:58:06.681: ERROR/AndroidRuntime(1552):  at dalvik.system.NativeStart.main(Native Method) 
+0

У меня были те же сообщения об ошибках от моих пользователей, у которых есть ОС версии 1.5, 2.1 и 2.2. Stacktrace не проходит через мой код, поэтому я не могу уловить эту ошибку - приложение заканчивается с помощью FC. – tomash

+0

Это действительно похоже на проблему фрагментации.Это похоже на то, что у моего приложения есть утечка памяти, которая распространяет крошечные фрагменты данных по всей области памяти кучи. Я бы предположил, что подобное поведение может быть улучшено в следующих версиях Dalvik, потому что это может быть не ошибка, но, конечно же, это не «хорошее поведение», так как на самом деле у вас есть память, но система не может ее использовать из-за ее фрагментации. Ну, я буду продолжать пытаться понять, что с этим можно сделать. –

+0

Я знаю, что прошло уже больше года с тех пор, как этот вопрос был задан, но есть решение для этой проблемы? Я curiuos. Заранее спасибо! – Ahmed

ответ

1

Я бежал в эту проблему и выключаться за прошедший месяц. Способ, которым я работал над проблемой в моем коде, - заставить GC очистить неописанные растровые изображения, которые я завернул в WeakReferences. Этот подход может не сработать для вас, так как сбой, который вы вставили выше, кажется, возникает в MapView. Независимо от того, попробуйте посыпать некоторые вызовы System.gc() в ключевых местах вашего кода и посмотреть системный журнал, чтобы узнать, показывают ли сообщения GC_EXPLICIT много освобожденных объектов/байтов. В коде, над которым я работаю, мне пришлось добавить System.gc() в конце моего метода Adapter.getView(), чтобы убедиться, что неиспользуемые растровые изображения очищены при следующем вызове getView(). Этот подход, судя по всему, резко сократил мой запуск с страшный java.lang.OutOfMemoryError: размер растрового изображения превышает крах бюджета VM.

+0

вызов System.gc() не должен помогать OOME. VM не собирается через OOME, прежде чем сначала попытаться запустить GC. Кроме того, System.gc() ничего не делает для фрагментации. –

+0

Эти ошибки OOME чаще происходят на телефонах семейства Galaxy, таких как Nexus One и Nexus S. Я не использовал Galaxy Nexus, чтобы проверить, действительно ли эта проблема больше на этом телефоне по сравнению с другими. Выбросить вызовы GC для очистки памяти вместе с тщательным кодированием, насколько мне известно, лучший способ избежать этой проблемы. Также можно поймать исключение (как Throwable) и, по крайней мере, предотвратить закрытие приложения. Но, к сожалению, я не уверен, есть ли окончательное решение для этой проблемы ... –

1

У меня была эта ТОЧНАЯ проблема, я сосал код с некоторыми вызовами System.GC, и это, казалось, помогло немного, но это все еще происходит.

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

Это все происходит только на HTC Desire, который, я считаю, является тем же телефоном, что и Nexus One под капотом. (и во многом подобным EVO, который также страдает от него).

Примечание: Он работает на 100% в нашем Arc-S, Galaxy V1, AVD-эмуляторе и планшете Asus.

1

Я имел такую ​​же проблему, добавьте следующую строку в файл манифеста под тег приложения

андроида: largeHeap = True. Это сработало для меня

+0

улучшает скорость сбоя, но не решает проблему полностью. –

+0

Это в основном резервное решение, если абсолютно ничего не работает. –

Смежные вопросы