On Android, I'm using Base64.decode() method. It has several variants, but all of them decode the given base64 input into a newly created byte array.
Since I need to call this a lot with big inputs, it allocates a lot of memory and causes frequent GC.
So I'm wondering if there is a way to pass an existing byte array to the method, or alternative techniques, so that it puts the result inside the existing byte array and avoid allocating memory for a new one.
That would be similar to the use of options.inBitmap in BitmapFactory when creating a bitmap in order to reuse an existing bitmap.
Thanks for your help
Related
I want to combine two Renderscript scripts into a scriptGroup. The first one is the ScriptIntrinsicBlur. Based on the blurred U8 allocation as input the second script calculates two things: gradient and gradient-direction. The latter is the formal out-Allocation of the second kernel. The first one is a global allocation filled via rsSetElementAt_float(). Now, I find this second allocation is returned empty after execution of the scriptGroup.
Question: Is my assumption correct that with a scriptGroup you cannot use script globals - or at least not change them via rsSetElementAt_(...)?
UPDATE: I realized that the performance gain by using U8 both as output of the ScriptIntrinsicBlur and as input of the proprietary kernel is already more than satisfactory, even in a simple sequential set-up of both scripts. This is primarily because it avoids to copyTo the ScriptIntrinsicBlur's out-Allocation first into a Java-array before passing it as a separate input-allocation to the 2nd kernel.
Before, I used U8_4 (i.e. Bitmap equivalent) as output of ScriptIntrinsicBlur, and then converted it to a one-dimensional greyscale int[] array, before passing it as in-Allocation to the proprietary kernel... Now I convert to greyscale byte[] (i.e. U8) already before entering the allocation into ScriptIntrinsicBlur and use U8 also as input for the 2nd kernel.
This is what I realize again and again when working with RS: it is really worth to simplify data flows to the extent possible, the speed gains are fantastic. (maybe I will check the Scriptgroup question at a later stage, as for now I am happy with the result).
There should be no issue with using a script global like this. It's not as efficient as the output allocation, but is possible. You mentioned the out allocation is empty, what are you seeing in the script global?
In my android application I have an large ArrayList of objects (more than 100), and I'm passing this ArrayList from activity to activity via the intents, using the putExtra(key,value) function. What exactly happens memory wise when I do such thing, does the ArrayList gets copied so now it occupies twice the memory it needed at first? or it jst get referenced so the space stays the same?
When you are passing your ArrayList, you are serializing/parceling it. This is called marshalling. On the other end, you are reading these parcels and doing unmarshalling. What it does is basically convert your ArrayList to stream that you read on the other end and making a COPY of the original.
I am developing an aplication where I need to read large image files (6000x6000) ,then applying some filtering (like blurring and color effects) and then saving the image.
The filtering library is a 3rd party library that is programmed in Java and take something like this as a input :
/**
* rgbArray : is an Array of pixels
*/
public int[] ImageFiltering(int[] rgbArray,int Width,int Height);
The problem is that if I load the image in memory (6000 x 6000 x 4 = 137.33 MB) android throws OutOfMemory error.
After reading some documentation and knowing that the memory allocated from NDK is not part of the application heap ,I get an interesting idea:
Open the image from NDK Read it contents and save it in an array
Pass the array back to Java
Apply filter to the array data
Return the array to NDK
Save the data array into a new image and release the array memory
Here is an example of NDK function with returns the big,fat array:
jint*
Java_com_example_hellojni_HelloJni_stringFromJNI( JNIEnv* env,jobject thiz,jint w,jint h)
{
int* pixels = (int*)malloc(w * h * 4);
read_image_into_array("image.jpg",pixels);
return pixels;
}
The goal is to reserve the memory in native in order to avoid getting OutOfMemory error,and pass the memory reference to Java in order to work with it.
Since I am have not C developer and have never touched JNI ,is all this making sense and how could it be implemented in NDK.
Use a direct ByteBuffer, using the allocated memory as its backing buffer. You can allocate a direct byte buffer from JNI (using NewDirectByteBuffer()) and return it.
You'll need to provide a complementary method for disposing of the memory or otherwise indicating to the native side that it is no longer in use.
I'm working with Android and I really need a fast way to get a bitmap of format BGRA to be filled in ARGB.
One thing I aslo want to let u know that The Data comes in byte[] format and I have to convert in int[] format also.
Can AnyOne Tell me How to do this ...
Thanks in Advance
If you want to load a Bitmap by bytestream, you can use Bitmap.decodeStream. You could then use getPixel(s?) to get the int array. This is one way I know how to do this, probably not the fastest though. A faster way would be to convert bytes to int, if your byte array is nothing but pixeldata this won't be too hard.
BGRA to ARGB can be done with bitshifting quite fast.
A nice source you would probably like:
https://web.archive.org/web/20141229164101/http://bobpowell.net/lockingbits.aspx
The fastest way I think would be to do it in native code using the NDK. I've been considering to use it for image processing for some time but didn't get the chance yet. So I don't know much about it (i.e. how you would access your byte buffer) but you could start from the Plasma sample for bitmap processing in JNI.
I am new on android and I am developing an application in which I am downloading images from server in drawable array. Everything is right but when the activity(in which drawables are downloade one by one in thread) loads, after some time it gives out of memory error.
Please help.
try to use streams instead loading it at once and use SoftReference. and read http://davidjhinson.wordpress.com/2010/05/19/scarce-commodities-google-android-memory-and-bitmaps/
It's not a memory leak you have, you're simply trying to put more images into memory at once than will fit
In order to solve that you can either
Use an array of SoftReference<Drawable>, store each drawable in the array as new SoftReference(myDrawable). When retrieving a SoftReference, check that SoftReference.get() is not null. If it is null the drawable has been reclaimed by the Garbage Collector (GC) and you will need to re-download it to memory, if it is not null then SoftReference.get() returns the drawable you stored in the SoftReference.
Limit the size of the array to an amount that will fit in memory. You will have to implement some system of storing new images over the older ones if the array has got to it;s maximum size (e.g. place the new image on the end of the array and remove the first element of the array)
SoftReferences allow the GC to reclaim the memory taken up by objects when low memory situations are encountered.