2016-08-16 4 views
0

В каком-то устройстве мое приложение имеет OutOfMemoryError со следующей трассировки стека:Как найти причину OutOfMemoryError?

java.lang.OutOfMemoryError: Failed to allocate a 16828428 byte allocation with 643016 free bytes and 627KB until OOM 
at dalvik.system.VMRuntime.newNonMovableArray(Native Method) 
at android.graphics.BitmapFactory.nativeDecodeAsset(Native Method) 
at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:856) 
at android.graphics.BitmapFactory.decodeResourceStream(BitmapFactory.java:675) 
at android.graphics.drawable.Drawable.createFromResourceStream(Drawable.java:2228) 
at android.content.res.Resources.loadDrawableForCookie(Resources.java:4211) 
at android.content.res.Resources.loadDrawable(Resources.java:4085) 
at android.content.res.Resources.getDrawable(Resources.java:2005) 
at android.content.res.Resources.getDrawable(Resources.java:1987) 
at android.content.Context.getDrawable(Context.java:464) 
at android.support.v4.content.ContextCompatApi21.getDrawable(ContextCompatApi21.java:26) 
at android.support.v4.content.ContextCompat.getDrawable(ContextCompat.java:321) 
at android.support.v7.widget.TintManager.getDrawable(TintManager.java:175) 
at android.support.v7.widget.TintManager.getDrawable(TintManager.java:168) 
at android.support.v7.widget.AppCompatImageHelper.setImageResource(AppCompatImageHelper.java:51) 
at android.support.v7.widget.AppCompatImageView.setImageResource(AppCompatImageView.java:72) 
at com.coulddog.loopsbycdub.application.fragment.implementation.MediaPlayerFragment.updatePlayButtons(MediaPlayerFragment.java:299) 
at com.coulddog.loopsbycdub.application.fragment.implementation.MediaPlayerFragment.setState(MediaPlayerFragment.java:288) 
at com.coulddog.loopsbycdub.application.fragment.implementation.MediaPlayerFragment$8.onClick(MediaPlayerFragment.java:278) 
at android.view.View.performClick(View.java:5697) 
at android.view.View$PerformClick.run(View.java:22526) 
at android.os.Handler.handleCallback(Handler.java:739) 
at android.os.Handler.dispatchMessage(Handler.java:95) 
at android.os.Looper.loop(Looper.java:158) 
at android.app.ActivityThread.main(ActivityThread.java:7225) 
at java.lang.reflect.Method.invoke(Native Method) 
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1230) 
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1120) 

Я не понимаю причину этой ошибки. Эта ошибка не произошла на моем устройстве. Итак, у меня есть два вопроса. Во-первых, можно сделать мое реальное устройство или эмулятором genymotion более чувствительным для OutOfMemoryError? И второй вопрос, каков возможный случай этой ошибки?

+3

файл изображения вы поставляете имеет такое большое разрешение, создавая изображение для него занимает слишком много памяти. – greenapps

+0

Возможный дубликат [Android: java.lang .OutOfMemoryError: не удалось выделить выделение байтов 23970828 с 2097152 бесплатными байтами и 2 МБ до OOM] (http: // stackoverflow.com/questions/32244851/androidjava-lang-outofmemoryerror-failed-to-allocate-a-23970828-byte-allocatio) – barq

ответ

2

Я бы сказал, что вы должны использовать LeakCanary, чтобы узнать утечку памяти, которая является большой библиотекой, разработанной Square Square Engineers. Кроме того, есть и другие инструменты, которые могут помочь вам обнаружить утечки памяти & оптимизировать утечки памяти, поэтому проверьте Best Practices for Performance с Android-документов.

Кроме того, в вашем случае вы загружаете растровые изображения с высоким разрешением, правильно управляя ими. Так что, лучше бы вы идете через мой this ответ, который основан на тему из Android Docs Displaying Bitmaps Efficiently

2

Ошибки гласит, что 16 MB изображение загружается в то время как память очень низкие.

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

Тогда 16 МБ все еще слишком велико. Сжатое изображение меньше, но здесь размер (ширина и высота) должен быть очень большим.

at com.coulddog.loopsbycdub.application.fragment.implementation.MediaPlayerFragment$8 
      .onClick(MediaPlayerFragment.java:278) 

Так что проверьте, что там происходит.

+1

Неверно, 16mb не gb. – barq

+0

@barq спасибо, исправлено. К счастью, это изображение 2000х2000 или такое чудовище. –

+0

Чем вы для вас отвечаете. Мой проект ясен из-за утечек памяти. Я знаю фрагмент, где это изображение пытается выделить память, но как я могу узнать, что это за изображение. В моем Android Studio в мониторах памяти я увидел, что фрагмент выделяет всего 3 Мб. Каждое из моих изображений размером менее 400 × 400 пикселей, а также я имею несколько изображений с девятью патчами с разрешением 1154 × 30 пикселей. – couldDog

1

Следуйте по желтой стековой дороге!

Ошибка OutOfMemory была удалена в классе BitmapFactory в функции "nativeDecodeAsset" функции "decodeStream" и так далее.

Эта функция называлась "createFromResourceStream" в Drawable. Еще несколько строк, которые вы видите, назывались формой Context#getDrawable.

Так и так далее, пока вы не нажмете com.coulddog.loopsbycdub.application.fragment.implementation.MediaPlayerFragment.updatePlayButtons(MediaPlayerFragment.java:299), что, очевидно, не является системным вызовом Android. Это будет то место, где вы загружаете изображение, которое оказалось слишком большим.

Итак, все это вместе, вы можете видеть, что есть изображение, которое просто далеко, слишком большое, чтобы быть выделенным. Кажется, что это изображение в вашей папке /res/drawable/ (как обозначено Context#getDrawable(). Изображение размером 16 МБ в этом случае. Не должно быть слишком сложно определить, какое изображение это.

+0

Отличный ответ. Спасибо вам. По этой строке я действительно установил один для ImageView. То, что доступно, составляет 400 x 400 пикселей. – couldDog

0

Вы можете использовать хорошую стороннюю библиотеку #Lalit Poptani

ИЛИ

в процессе разработки вы можете проверить состояние памяти на мониторы, который поставляется в разделе Android Monitor в Android Studio.

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