In my Android application the requirement is to fetch the images from the server and cache them into the heap memory.
On receiving the request, the server first encodes the byte[]
into Base64String
and returns that string. And, at the time of rendering it into ImageView
the Android application decodes the Base64String
back to the byte[]
, creates a Bitmap
, and puts it on ImageView
.
As everything is in cache, there are chances the Application to go out of memory at some point, and crash critically.
To prevent the out of memory situation, I have defined a safety quantum (E.g. 5 MB) in my application. If at any point the available memory goes below to this safety quantum, user would then need to mark some of the images as the candidates to be deleted. Along with, the application would show the estimated memory going to be released once the selected items are cleared.
The Bitmap
has been recycled once user moves away from the image, so the Bitmap
effectively isn't holding any memory as long as we are away.
In a particular test, I download 55 images, and my heap grows from 16 MB
to 42 MB
. That means, 55 images occupy 26 MB
. After I clear all of them, the heap shrinks back to 16 MB
.
But, when I take a cumulative sum of lengths of all Base64String
it comes to 11983840
. And if I consider one character as 1 byte
the 11983840 bytes
makes 11.4 MB
The problem is, cumulative sum of the lengths of Base64String
is the only measure available to me, that helps to let user know how much memory can be released by his selection.
I have also read the following question, which mentions, for each 3 Bytes
of original data the Base64String
will have 4 Characters
.
Base64 length calculation?
The question is,
a single character in Base64String
holds how many bytes? 1, 2 or more
If 1 character
is 1 byte
,
and in my test the heap grows and shrinks by 26 MB. Then why the cumulative sum of the lengths of Base64String
is only 11.4 MB?
Updated
This means 1 Byte
per character.
The default CharacterSet here is UTF-8
Each Base64 digit represents exactly 6 bits of data. So, three 8-bits bytes of the input string/binary file (3×8 bits = 24 bits) can be represented by four 6-bit Base64 digits (4×6 = 24 bits). This means that the Base64 version of a string or file will be at least 133% the size of its source (a ~33% increase).
There are many ways to do this, but the way we are covering now is by using base64 encoding. The 256 characters in the ASCII character set are numbered 0 through 255. For the tech savvy, this is the same as 28, 8 binary placeholders, or a byte.
Encode files to Base64 formatThe maximum file size is 192MB. Destination character set for text files.
Lets start from the beginning...
Base64 is an encoding format based upon a set of 64 characters - each character is worth 6 bits of data (2^6 = 64). So when converting, each 8-bit byte of input needs (8 / 6) = 1.333333... characters.
But since computers only store whole bytes, it's easier to say that for every 3 bytes (3*8=24 bits) of input, 4 base-64 characters are produced (4*6=24 bits).
Now, you say your base-64 string total length is 11 million characters. In Java, strings are stored in 16-bit Unicode format: 1 character = 2 bytes.
So 11 million characters will use over 20 MB just in the raw character data. That, combined with objects, variables and other state needed to store the information means that 26 MB is a reasonable value for the amount of data you are using.
So a general rule you might want to use to estimate memory usage is (((input_data_in_bytes * 4/3) * 2) + a few MB)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With