Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Excessive GC use #19

Open
Dr-Emann opened this issue Mar 21, 2014 · 5 comments
Open

Excessive GC use #19

Dr-Emann opened this issue Mar 21, 2014 · 5 comments

Comments

@Dr-Emann
Copy link
Contributor

The Garbage Collector is being run (GC_FOR_MALLOC) on every blur because we're creating a new bitmap on every call. There's two ways to try to fix this.

Explicit Bitmap Re-use

The usual solution to this problem is to allow the user to pass an existing bitmap in.

StackBlurManager manager = new StackBlurManager(bitmap);
Bitmap output = Bitmap.createBitmap(
    bitmap.getWidth(),
    bitmap.getHeight,
    Bitmap.Config.ARGB_8888
);
manager.process(10, output);

Pros

  • No possible breaking changes with existing code
  • The user gets to choose if they need to recycle the bitmap

Cons

  • Most uses could benefit from recycling, but the user has to explicitly do so

Implicit Bitmap Re-use

However, because we have the StackBlurManager class which already holds a reference to the result, we could possibly reuse that bitmap. This could possibly break some existing code though! If the user holds on to a reference to the blurred bitmap, then blurs again, the first reference will be modified to be the same as the second. For example:

StackBlurManager manager = new StackBlurManager(bitmap);
Bitmap blur5px = manager.process(5);
Bitmap blur10px = manager.process(10);
// blur5px and blur10px are the same Bitmap, and both are blurred by 10px.
// The user would have to explicitly copy the bitmap if they want control of it.
Bitmap correct_blur5px = manager.process(5).copy(Bitmap.Config.ARGB_8888, false);

Another possible problem arises if the user tries to recycle the image.

StackBlurManager manager = new StackBlurManager(bitmap);
Bitmap tmp = manager.process(5);
tmp.recycle();
// User thinks they're cleaning up after themselves, but the bitmap is
// owned by the StackBlurManager.

The StackBlurManager can check if the image has been recycled before trying to blur into it, and make a new bitmap if it has been, possibly putting something in the log letting the user know they shouldn't call recycle on bitmaps owned by the manager.

Pros

  • Bitmaps are automatically recycled, using the existing _result variable in the StackBlurManager

Cons

  • Possible code breakage
@kikoso
Copy link
Owner

kikoso commented Apr 6, 2014

Hello @Dr-Emann ,

I would say the explicit option has bigger advantages rather than the implicit. We are supporting existing code, but from now on the user can also use a new feature to improve performance - in the case he was having performance problems, I do not think this will happen if they are blurring single images.

What are your thoughts?

@Dr-Emann
Copy link
Contributor Author

Dr-Emann commented Apr 7, 2014

I agree. I've set up something here: https://github.com/Dr-Emann/android-stackblur/tree/less_garbage. I'll have to clean it up a little, and submit a pull request.

@kikoso
Copy link
Owner

kikoso commented Apr 24, 2014

Cool :-). Looking forward!

@randomrandom
Copy link

Hi guys, I'm currently experiencing Out of memory exceptions. I use your library to blur single images in separate activities, but it seems that on lower-end devices this causes out of memory exceptions after some time. I managed to reduce the exceptions by scaling down the image 3 times before I pass to the StackBlur and then scaling it back to normal, but this produces lower image quality. Do you have any progress on the issue? I'm currently using the .process(radius) method. I haven't tried the processNatively method, do you think it would make a difference?

@kikoso
Copy link
Owner

kikoso commented Aug 2, 2014

Hello @randomrandom ,

Old and low end devices might have problems running the library. Are you running the Java method? Running the NDK or RenderScript process definitely helps in terms of optimization, but still some devices might not be able to process it.

http://developer.android.com/training/displaying-bitmaps/index.html

I fear that in that case the only solution is to reduce the image size

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants