0

I have somehow a complex app, it has a lot of images and bitmaps and icons after using the app for a while I'm getting out of memory exception when trying to inflate a layout, the exception is being thrown by the bitmap factory (As expected)

the thing is there is no page that crashes on it's own, I'm not using very large pictures and most of them are web requests using volley

Here is the scenario: I have an activity with a fragment in it, I switch to the other fragment that has around 15 image all of them are coming using Volley with a BitmapLruCache implemented (correctly I suppose), this fragment works just fine, getting back to the previous fragment works just fine as well. However, going back and forth between these two fragments suddenly raises OOM Exception, I'm not keeping the fragment in memory , I tried to replace and remove the fragment using the fragment transaction the problem still exists

the first fragment has 3 static pictures and some others are web requests

I searched for the solution but everything suggests solutions when the problem is persistent on some point of the app

What is the general way to deal with this? is there a way to dispose/clear the cache or the heap, when I change the fragment the old one is not needed at all

I would have put some code but I don't know where to start!!

any suggestions?

EDIT: I disabled volley requests , my app has no web bitmaps now

This is how I sat up the BitmapLruCache

public class BitmapLruCache extends LruCache<String, Bitmap> implements ImageLoader.ImageCache {
public static int getDefaultLruCacheSize() {
    final int maxMemory = (int) (Runtime.getRuntime().maxMemory() / 1024);
    final int cacheSize = maxMemory / 8;

    return cacheSize;
}

public BitmapLruCache() {
    this(getDefaultLruCacheSize());
}

public BitmapLruCache(int sizeInKiloBytes) {
    super(sizeInKiloBytes);
}

@Override
protected int sizeOf(String key, Bitmap value) {
    return value.getRowBytes() * value.getHeight() / 1024;
}

@Override
public Bitmap getBitmap(String url) {
    return get(url);
}

@Override
public void putBitmap(String url, Bitmap bitmap) {
    put(url, bitmap);
}
}

EDIT 2: I'm observing the memory graph in android studio,each jump in the graph is actually a change between the fragments, but as I mentioned before, how do I get rid of the fragment?! I tried to remove it before

memory graph

EDIT 3: here are the logs for one of the exceptions (as I mentioned it doesn't always happen at the same point of the app)

12-10 19:44:29.396 29021-29021/com.orderme E/AndroidRuntime: FATAL EXCEPTION: main
                                                         Process: com.orderme, PID: 29021
                                                         java.lang.OutOfMemoryError: Failed to allocate a 5040012 byte allocation with 3173020 free bytes and 3MB until OOM
                                                             at dalvik.system.VMRuntime.newNonMovableArray(Native Method)
                                                             at android.graphics.BitmapFactory.nativeDecodeAsset(Native Method)
                                                             at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:726)
                                                             at android.graphics.BitmapFactory.decodeResourceStream(BitmapFactory.java:547)
                                                             at android.graphics.drawable.Drawable.createFromResourceStream(Drawable.java:1014)
                                                             at android.content.res.Resources.loadDrawableForCookie(Resources.java:3747)
                                                             at android.content.res.Resources.loadDrawable(Resources.java:3620)
                                                             at android.content.res.TypedArray.getDrawable(TypedArray.java:762)
                                                             at android.widget.ImageView.<init>(ImageView.java:151)
                                                             at android.widget.ImageView.<init>(ImageView.java:140)
                                                             at android.support.v7.widget.AppCompatImageView.<init>(AppCompatImageView.java:60)
                                                             at android.support.v7.widget.AppCompatImageView.<init>(AppCompatImageView.java:56)
                                                             at android.support.v7.internal.app.AppCompatViewInflater.createView(AppCompatViewInflater.java:98)
                                                             at android.support.v7.app.AppCompatDelegateImplV7.createView(AppCompatDelegateImplV7.java:926)
                                                             at android.support.v7.app.AppCompatDelegateImplV7.onCreateView(AppCompatDelegateImplV7.java:980)
                                                             at android.support.v4.view.LayoutInflaterCompatHC$FactoryWrapperHC.onCreateView(LayoutInflaterCompatHC.java:44)
                                                             at android.view.LayoutInflater$FactoryMerger.onCreateView(LayoutInflater.java:181)
                                                             at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:732)
                                                             at android.view.LayoutInflater.rInflate(LayoutInflater.java:813)
                                                             at android.view.LayoutInflater.inflate(LayoutInflater.java:511)
                                                             at android.view.LayoutInflater.inflate(LayoutInflater.java:415)
                                                             at android.view.LayoutInflater.inflate(LayoutInflater.java:366)
                                                             at com.orderme.Main.MainFragment.onCreateView(MainFragment.java:105)
                                                             at android.support.v4.app.Fragment.performCreateView(Fragment.java:1965)
                                                             at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1078)
                                                             at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1259)
                                                             at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:738)
                                                             at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1624)
                                                             at android.support.v4.app.FragmentManagerImpl$1.run(FragmentManager.java:517)
                                                             at android.os.Handler.handleCallback(Handler.java:739)
                                                             at android.os.Handler.dispatchMessage(Handler.java:95)
                                                             at android.os.Looper.loop(Looper.java:145)
                                                             at android.app.ActivityThread.main(ActivityThread.java:5951)
                                                             at java.lang.reflect.Method.invoke(Native Method)
                                                             at java.lang.reflect.Method.invoke(Method.java:372)
                                                             at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1388)
                                                             at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1183)
Hassan Khallouf
  • 1,170
  • 1
  • 13
  • 30
  • "the first fragment has 3 static pictures" - If by "static" you mean the `static` modifier sounds like this could cause a memory leak. Have you tried the debugging steps in the [Android docs](http://developer.android.com/tools/debugging/debugging-memory.html)? – PPartisan Dec 09 '15 at 17:29
  • no I didn't mean static modifiers, I meant static as in the drawables and not from the internet – Hassan Khallouf Dec 09 '15 at 17:30
  • can you post more info (dimension of largest asset bucket) about these images? what xml layout you are using to display them? – petey Dec 09 '15 at 17:37
  • can you also add you BitmapLruCache setup? – petey Dec 09 '15 at 18:02
  • check my edit please – Hassan Khallouf Dec 09 '15 at 18:12
  • http://stackoverflow.com/a/21913303/794088 will be helpful if you go largeheap. Are you getting any outofmemory exceptions when using your app? – petey Dec 10 '15 at 16:29
  • What are the disadvantages of marking my app as "large heap"? And what do mean if I'm getting out of memory exception. . Of course I do this is my question – Hassan Khallouf Dec 10 '15 at 16:33
  • ok...please post those OutOfMemory exception logs. they will help you fgure out what needs fixing/adjustment. – petey Dec 10 '15 at 16:39
  • it can happen it any point of the app, memory gets full when ever I change a fragment, not "the" fragment, any fragment might fire the exception when the memory is full, I will post a random one of them – Hassan Khallouf Dec 10 '15 at 16:44

2 Answers2

0

15 images are not a big deal assuming each is of size 5mb even. Verify whether caching working properly or not in volley. Few image libraries does not delete the cache when the images are no more required or when heap is growing high. Say picasso doesn't do that. I had similar situation where if u scroll up and down through friends list there was OOM. I was using picasso lib. I switched to UIL with which I did not see the OOM again. In picasso I hag to handle deleting cache though it was bit hectic. In UIL I did not need to do that.

So see if volley does not delete cache by default and if you've to do that.

You may take a look at this SO post.

Community
  • 1
  • 1
cgr
  • 4,578
  • 2
  • 28
  • 52
  • *each is of size 5mb even* ... size of what ? jpg, png or native bitmap's data? if jpg or png then it is way too big to store it in memory (as it will implicate size like 4096x4096(or similar monster size) - and as native bitmap it will takes ~64MB - for ARGB8888) – Selvin Dec 09 '15 at 17:44
  • filesize has nothing to do with bitmap memory usage. using ARGB_8888 a 10x10 pixel image will take 10x10x4 (400) bytes of memory when decoded (doesnt matter if the jpg is 1mb or 2kb on disk) – petey Dec 09 '15 at 18:05
  • That's what I wrote... But OP may thinks different. – Selvin Dec 10 '15 at 22:40
0

Problem Solved! After 4 days of trials and heap dumping and everything it turned out it's not in my code

I downgraded zendesk library to an older version it was solved!

Hassan Khallouf
  • 1,170
  • 1
  • 13
  • 30