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