OutOfMemoryError and downsampling in 2.7 beta

Creaky

Member
Licensed User
Longtime User
Hi Erel!

I'm currently working on an app that uses very large images, and on some of my test devices these images cause unpredictable OutOfMemoryError problems.
So you can imagine that I was really looking forward to the new automatic downsampling functionality to prevent OutOfMemoryError errors!

It does it's job well, but (there is always a but)...
In b4a 2.50 I was able to use 3000x3000px bitmaps on almost ALL of my test devices without running into OutOfMemoryError's . But with b4a 2.7 beta I'm only able to use 2000x2000px images before the downsampling functionality kick in! That's a 33% decrease in usable image size, while the 3000x3000px images did not cause OutOfMemoryError's before.

Is there a way to control the 'cut-off' threshold of the downsampling functionality? If not, is it still possible to ask for one in the 2.7 release version?
 

Erel

B4X founder
Staff member
Licensed User
Longtime User
I will explain. On Android 4+ devices hardware acceleration (OpenGL) is active by default. OpenGL implementation in Android is limited to images of 2048x2048. Larger images will just not be displayed.

It is better to display a downsampled image than a black image. I will however check whether it is possible to allow larger images if such are supported.
 
Upvote 0

Creaky

Member
Licensed User
Longtime User
Hi Erel,

Because I use a TouchImageView to display the large bitmaps, I have explicitly turned hardware acceleration off through the manifest (SetApplicationAttribute(android:hardwareAccelerated,"false")).
So my app really shouldn't be using OpenGL in 2.7.

The fact that I can use 3000x3000px bitmaps in B4A 2.52, proves the fact that OpenGL is not active in my app.

Does the downsampling function simply downsample every bitmap larger than 2048x2048px, regardless whether hardware acceleration is turned on or off?
 
Upvote 0

Asmoro

Active Member
Licensed User
Longtime User
Hi,

I also had a lot of images but not that big as yours in my app and getting
out of memory issues as well.

So I put the line underneath in the manifest editor :

SetApplicationAttribute(android:largeHeap,"true")

Means using max of (available) memory size.

Just try and see if it works.

Asmoro
 
Upvote 0

Informatix

Expert
Licensed User
Longtime User
Hi,

I also had a lot of images but not that big as yours in my app and getting
out of memory issues as well.

So I put the line underneath in the manifest editor :

SetApplicationAttribute(android:largeHeap,"true")

Means using max of (available) memory size.

Just try and see if it works.

Asmoro

Using a large heap is like hiding your bad coding under the carpet. Try to improve your code instead of requesting a lot of memory for your app.
That being said, you're facing maybe the same problem as I have. I'm going to use a large heap in my latest project because I have a lot of memory leaks that I can not find the origin nor the reason. All allocated data are freed before leaving the activity (I nullify each bitmap, each object, etc., just to be sure), but I cannot never revert to the memory level that I had before entering the activity. Are the leaks in the B4A code? I cannot say.
DDMS doesn't help me on that point because the informations are too vague. It's frustrating.
 
Upvote 0

Asmoro

Active Member
Licensed User
Longtime User
Yes, it's really frustrating for me too.

I really don't know if it's about 'hiding bad coding', but I do know that
after resizing the image size and resolutions plus with coding to stop all the activities when you switch to another activity, I don't have issues anymore.

I do hope however that once you quit the app, the available memory will
return back for other needs. (gonna check with some kind of an app)

Let's hope that Erel will find a great solution for this important issue.
 
Upvote 0

Informatix

Expert
Licensed User
Longtime User
after resizing the image size and resolutions

Resizing a bitmap is probably the first thing to do before using it. That may save a lot of memory. If your screen is unable to display more than 800x480, what's the usefulness to keep in memory an image of 3000x3000? It's a waste of memory that may lead to troubles.
Frankly speaking, I can't see any reason to use a very large bitmap, whatever app you're working on. In games or in cartography apps, a tile system is used (parts of the image are loaded when needed). In an image processing app, what you display is not what you process (you process the whole file, with its native resolution, but you don't display the image with its native resolution, only a version resized for the screen). To avoid loading fully the file in memory, you use a stream (Input/Output streams).

I do hope however that once you quit the app, the available memory will
return back for other needs. (gonna check with some kind of an app)

It depends. Quitting your activity does not mean "ending" it. It stays in memory until another process claims resources. But as the OS will free any memory it needs, you can be sure that your quitted app won't hold any memory.
 
Last edited:
Upvote 0

Creaky

Member
Licensed User
Longtime User
Does that mean the functionality is now completely turned off?
That would be a shame, because if OpenGL acceleration is used the check would be a great help.
Is there no way to detect that hardware acceleration is turned off and then turn off the check to? (And visa versa)
 
Upvote 0

Erel

B4X founder
Staff member
Licensed User
Longtime User
Does that mean the functionality is now completely turned off?
Only the maximum size check is disabled. Images will still be downsampled as a result of out of memory errors.

@Asmoro, you should use LoadBitmapSample instead of LoadBitmap. The new feature in v2.70 will also solve these memory issues though it is still better to explicitly set the required size.
 
Upvote 0

Creaky

Member
Licensed User
Longtime User
Why do you turn the hardware acceleration off?

As I've stated in my OP, I use WarWound's excellent TouchImageView. An ImageView especially optimised for use with large bitmaps without having to use complicated tiling mechanisms. TouchImageView requires you to turn off hardware acceleration (And we now know why, it's neccesary to circumvent the size limitations of OpenGL).
 
Last edited:
Upvote 0

Creaky

Member
Licensed User
Longtime User
Only the maximum size check is disabled. Images will still be downsampled as a result of out of memory errors.

So as long as an OutOfMemoryError doesn't occur, the downsampling functionality will leave the bitmap alone?
 
Upvote 0

Asmoro

Active Member
Licensed User
Longtime User
@Asmoro, you should use LoadBitmapSample instead of LoadBitmap. The new feature in v2.70 will also solve these memory issues though it is still better to explicitly set the required size.

Thanks Erel, I will look into it.

Note. Just a little wish...:

B4X:
Sub Activity_Pause (UserClosed As Boolean)
   Memory.Clear
   Activity.CloseMenu
End Sub
 
Last edited:
Upvote 0
Top