wasabeef / Blurry

Blurry is an easy blur library for Android
Apache License 2.0
5.57k stars 602 forks source link

java.lang.OutOfMemoryError #56

Open IlanVokov opened 7 years ago

IlanVokov commented 7 years ago

java.lang.OutOfMemoryError: Failed to allocate a 14745612 byte allocation with 13108268 free bytes and 12MB until OOM at dalvik.system.VMRuntime.newNonMovableArray(Native Method) at android.graphics.Bitmap.nativeCreate(Native Method) at android.graphics.Bitmap.createBitmap(Bitmap.java:812) at android.graphics.Bitmap.createBitmap(Bitmap.java:789) at android.graphics.Bitmap.createBitmap(Bitmap.java:720) at android.graphics.Bitmap.createScaledBitmap(Bitmap.java:596) at jp.wasabeef.blurry.internal.Blur.of(Blur.java:78) at jp.wasabeef.blurry.internal.Blur.of(Blur.java:41) at jp.wasabeef.blurry.Blurry$Composer.onto(Blurry.java:121)

does any one have a solution?

chrisblessing commented 6 years ago

Couple things you can try:

In your AndroidManifest for your try specifying:

android:largeHeap="true"

(ref: https://developer.android.com/guide/topics/manifest/application-element.html#largeHeap)

Also I do a memory check (although it doesn't always reflect reality at the time of execution) before I try to blur a large bitmap (we're working with movie boxart in my case, so some of these things are 5-7MB in size). Here's my little Memory class I use:

public class Memory {

    private static final String TAG = "util.Memory";

    // Get a MemoryInfo object for the device's current memory status.
    public static ActivityManager.MemoryInfo getAvailableMemory(Context context) {
        ActivityManager activityManager = (ActivityManager) context.getSystemService(ACTIVITY_SERVICE);
        ActivityManager.MemoryInfo memoryInfo = new ActivityManager.MemoryInfo();
        activityManager.getMemoryInfo(memoryInfo);
        return memoryInfo;
    }

    public static void logMemoryInfo(Context context) {
        ActivityManager.MemoryInfo memoryInfo = getAvailableMemory(context);

        Log.d(TAG, "Memory info:");
        Log.d(TAG, "\t                           avail mem: " + memoryInfo.availMem + " bytes (" + memoryInfo.availMem / 1024 / 1024 + "Mb)");
        Log.d(TAG, "\t                           total mem: " + memoryInfo.totalMem + " bytes (" + memoryInfo.totalMem / 1024 / 1024 + "Mb)");
        Log.d(TAG, "\tthreshold for low mem (of avail mem): " + memoryInfo.threshold + " bytes (" + memoryInfo.threshold / 1024 / 1024 + "Mb)");
    }

    public static boolean isLowOnMemory(Context context, boolean log) {
        if(context == null) {
            Log.w(TAG, "Attempt to check memory available without application context; returning true (blindly)");
            return false;   // we don't know without the context!
        }

        if(log) {
            logMemoryInfo(context);
        }

        return getAvailableMemory(context).lowMemory;
    }

}
asadmukhtar28 commented 5 years ago

@chrisblessing That class is not properly working and after reading in Android Docs use onTrimMemory callback instead of using isLowOnMemory but both events are not working.