0

In some device my application has an OutOfMemoryError with the following stack trace:

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)

I don't understand the cause of this error. This error has not happened on my device. So, I have two questions. First, is possible to make my real device or genymotion emulator more sensitive for OutOfMemoryError? And second question, what is the possible case of this error?

Kcvin
  • 5,073
  • 2
  • 32
  • 54
couldDog
  • 182
  • 2
  • 12
  • 3
    The image file you supply has such a big resolution that creating a bitmap for it takes too much memory. – greenapps Aug 16 '16 at 13:19
  • Possible duplicate of [Android:java.lang.OutOfMemoryError: Failed to allocate a 23970828 byte allocation with 2097152 free bytes and 2MB until OOM](http://stackoverflow.com/questions/32244851/androidjava-lang-outofmemoryerror-failed-to-allocate-a-23970828-byte-allocatio) – barq Aug 16 '16 at 13:30

4 Answers4

2

I would say that you should use LeakCanary to find out memory leaks, which is a great library developed by Square Square Engineers. Also, there are other tools which can help you to detect memory leaks & optimize memory leaks so checkout Best Practices for Performance from Android docs.

Also, in your case you are loading Bitmaps with high resolution properly managing them. So, better would be you go through my this answer which is based on a topic from Android Docs Displaying Bitmaps Efficiently

Community
  • 1
  • 1
Lalit Poptani
  • 67,150
  • 23
  • 161
  • 242
2

The error reads that a 16 MB image is loaded whereas memory is very low.

The low memory might be a hint to look for leaks, like image reading not closed or such.

Then 16 MB is still too large. Compressed the image is smaller, but here the size (width and height) must be very large.

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

So check what is happening there.

Joop Eggen
  • 107,315
  • 7
  • 83
  • 138
  • 1
    Wrong, 16mb not gb. – barq Aug 16 '16 at 13:27
  • @barq thanks, corrected. Fortunately that still is a 2000x2000 image or such monstrosity. – Joop Eggen Aug 16 '16 at 13:38
  • Than you for you answer. My project is clear from memory leaks. I know the fragment where that image try to allocate memory, but how can I know what that image is. In my Android Studio in Memory Monitors I saw that fragment allocate only 3 mb. Every of my images smaller than 400 × 400 px and also I have few nine-patch images with resolution 1154 × 30 px. – couldDog Aug 17 '16 at 07:19
  • I see `setState` and especially `updatePlayButtons` in the stack trace as immediate cause - as did you. Sorry I cannot help. Other than suggesting a try-catch in updatePlayButtons, and outputting the image info. Maybe a switch to circumvent images, enabled for that specific device. – Joop Eggen Aug 17 '16 at 07:45
1

Follow the yellow stack road!

The OutOfMemory error was hit in the BitmapFactory class in the "nativeDecodeAsset" function to the "decodeStream" function and so on.

This was called "createFromResourceStream" function in Drawable. A few more lines down you see it was called form the Context#getDrawable method.

So on and so forth until you hit com.coulddog.loopsbycdub.application.fragment.implementation.MediaPlayerFragment.updatePlayButtons(MediaPlayerFragment.java:299) which is obviously not an Android system call. This would be where you're loading an image that ended up being too large.

So put it all together you can see that there's an image that's just far, far too large to be allocated. It seems to be an image in your /res/drawable/ folder (as denoted by Context#getDrawable(). A 16 MB sized image at that. It shouldn't be too hard to figure out which image this is.

DeeV
  • 35,865
  • 9
  • 108
  • 95
  • Great answer. Thanks you. By this line I really set one drawable to ImageView. That drawable is 400 x 400 px. – couldDog Aug 17 '16 at 07:25
0

You can use good third party library #Lalit Poptani

OR

During development you can check memory status at Monitors which comes under Android Monitor section in android studio.

ViramP
  • 1,659
  • 11
  • 11