Sunil Chaudhary
Sunil Chaudhary

Reputation: 1247

Grow heap (frag case) to 8.837MB for 6220816-byte allocation error

I am trying to use 15 to 20 images to show on livewallpaper background one by one on a fix time ,but I am facing grow heap problem (Grow heap (frag case) to 8.987MB for 6220816-byte allocation) I have search everything but couldn't get through this Any help pleas.

here is my code

public class LiveWallpaperService extends WallpaperService {

private float x;
private int y;
private int angle;
private int speed;

@Override
public void onCreate() {
    super.onCreate();
}

@Override
public void onDestroy() {
    super.onDestroy();
}

@Override
public Engine onCreateEngine() {
    stopSelf();
    return new MyWallpaperEngine();
}

class MyWallpaperEngine extends Engine {

    private final Handler handle = new Handler();
    private final Runnable drawRunner = new Runnable() {

        @Override
        public void run() {
            draw();
        }
    };

    private Boolean visble = true;
    public Bitmap mBackgroundImage;
    public String name;
    int[] mImagesArray;
    private int mImagesArrayIndex = 0;

    MyWallpaperEngine() {

        mImagesArray = new int[] { R.drawable.love_1_mini,
                R.drawable.love_2_mini, R.drawable.love_3_mini,
                R.drawable.love_4_mini, R.drawable.love_5_mini,

                R.drawable.love_6_mini, R.drawable.love_7_mini,
                R.drawable.love_8_mini, R.drawable.love_9_mini,
                R.drawable.love_10_mini,

                R.drawable.love_11_mini, R.drawable.love_12_mini,
                R.drawable.love_13_mini, R.drawable.love_14_mini,
                R.drawable.love_15_mini, R.drawable.love_16_mini,
                R.drawable.love_17_mini, R.drawable.love_18_mini,
                R.drawable.love_19_mini, R.drawable.love_20_mini };

        if (mImagesArrayIndex == 0) {
            x = -330; // initialize x position
            y = 0; // initialize y position
        } else {
            x = -330; // initialize x position
            y = 0; // initialize y position
        }

    }

    @Override
    public Bundle onCommand(String action, int x, int y, int z,
            Bundle extras, boolean resultRequested) {
        return super.onCommand(action, x, y, z, extras, resultRequested);
    }

    @Override
    public void onCreate(SurfaceHolder surfaceHolder) {
        super.onCreate(surfaceHolder);
    }

    @Override
    public void onOffsetsChanged(float xOffset, float yOffset,
            float xOffsetStep, float yOffsetStep, int xPixelOffset,
            int yPixelOffset) {
        draw();
    }

    @Override
    public void onSurfaceCreated(SurfaceHolder holder) {
        super.onSurfaceCreated(holder);
        this.visble = false;

    }

    @Override
    public void onTouchEvent(MotionEvent event) {

    }

    @Override
    public void onVisibilityChanged(boolean visible) {
        this.visble = visible;
        if (visible) {
            handle.post(drawRunner);
        } else {
            handle.removeCallbacks(drawRunner);
        }

        super.onVisibilityChanged(visible);
    }

    private void incrementCounter() {
        mImagesArrayIndex++;
        if (mImagesArrayIndex >= mImagesArray.length) {
            mImagesArrayIndex = 0;

        }

    }

    @SuppressWarnings("deprecation")
    void draw() {

        int count = mImagesArray[mImagesArrayIndex];
        final SurfaceHolder holder = getSurfaceHolder();
        Canvas c = null;
        int scale = 2;
        Resources res = getResources();
        BitmapFactory.Options o2 = new BitmapFactory.Options();
        o2.inPreferredConfig = Bitmap.Config.RGB_565;
        o2.inSampleSize = scale;
        o2.inPurgeable = true;
        o2.inInputShareable = true;
        Bitmap image = BitmapFactory.decodeResource(res, count, o2);

        Calendar mCalendar = Calendar.getInstance();
        int h = mCalendar.get(Calendar.HOUR);
        int m = mCalendar.get(Calendar.MINUTE);
        int s = mCalendar.get(Calendar.SECOND);

        if (s == 10) {
            mImagesArrayIndex = 0;
        }

        try {
            Paint paint = new Paint(Paint.FILTER_BITMAP_FLAG);
            c = holder.lockCanvas();
            c.drawColor(Color.RED);

            if (c != null) {
                int a = 0;
                int counting = 0;
                if (counting == a) {
                    a++;
                    counting++;

                    c.drawBitmap(image, x, y, paint);

                    int widthhhh = c.getWidth();

                    x = (float) (x + 10.10);

                    if (x > widthhhh + 400) {

                        image.recycle();
                        image = null;
                        incrementCounter();

                    }

                }

                paint.setColor(Color.RED);

            }

        } catch (IllegalArgumentException e) {
            e.printStackTrace();
        } finally {

            try {
                if (c != null) {
                    holder.unlockCanvasAndPost(c);
                }
                handle.removeCallbacks(drawRunner);
                if (visble) {
                    handle.postDelayed(drawRunner, 10);
                }
            } catch (IllegalArgumentException e) {
                e.printStackTrace();
            }
        }
    }

}

}

Upvotes: 1

Views: 3251

Answers (2)

David Wasser
David Wasser

Reputation: 95578

In your draw() method, you have this code:

    Bitmap image = BitmapFactory.decodeResource(getResources(),
            mImagesArray[mImagesArrayIndex]);
    int count = mImagesArray[mImagesArrayIndex];
    final SurfaceHolder holder = getSurfaceHolder();
    Canvas c = null;
    int scale = 4;
    Resources res = getResources();
    BitmapFactory.Options o2 = new BitmapFactory.Options();
    o2.inPreferredConfig = Bitmap.Config.RGB_565;
    o2.inSampleSize = scale;
    o2.inPurgeable = true;
    o2.inInputShareable = true;
    image = BitmapFactory.decodeResource(res, count, o2);

Notice the first line calls BitmapFactory.decodeResource() and assigns the result to variable image and then later, the last line again calls BitmapFactory.decodeResource() and assigns the result to variable image. You never called recycle() on the first decoded image, so this is giving you a memory leak.

Upvotes: 1

mjstam
mjstam

Reputation: 1079

Bitmap image = BitmapFactory.decodeResource(getResources(), mImagesArray[mImagesArrayIndex]);

When your done with it call image.recycle() (see javadoc).

Upvotes: 1

Related Questions