Manipulating 256x256 bitmap crashing android-ndk's JNI - android

Perhaps I am attempting to do something I ought not.
I'm running a block of code in the emulator. It looks (more or less)
like this: http://pastie.org/1291380
This is to construct a live wallpaper background. I pass in a bitmap,
color palette, and tile array.The size of my bitmap is 256 x 256.
getRedPal / getGreenPal / getBluePal essentially does a call to
Color.red() / Color.green() / Color.blue() in order to get the rgb
color components of a palette object.
The loops chug along; I get all the way to the point where the j value
of drawInC hits 32, before the emulator crashes and burns:
11-11 15:34:44.032: INFO/distort_bmp(598): DrawInC: i: 0 j: 32
11-11 15:34:44.032: INFO/distort_bmp(598): DrawTiles: i: 0 j: 0
11-11 15:34:44.032: INFO/distort_bmp(598): DrawTiles: i: 0 j: 1
11-11 15:34:44.032: INFO/distort_bmp(598): DrawTiles: i: 0 j: 2
11-11 15:34:44.032: INFO/distort_bmp(598): DrawTiles: i: 0 j: 3
11-11 15:34:44.032: INFO/distort_bmp(598): DrawTiles: i: 0 j: 4
After which I get a dump file sent to /data/tombstones . Here is the
dump (but I sincerely don't find anything in it worth any value, just
a bunch of memory addresses): http://pastie.org/1291394
I added android:vmSafeMode="true" to my tag after
reading elsewhere that that could solve a problem. This is on 2.2,
using bitmap.h.
Personally I am dubious of that
jbyte* buffer =
(*env)->GetByteArrayElements(env, arr, &isCopy)
call; I plucked that
code from the net somewhere, as I was totally unable to get values
from my byte array "arr."
Any ideas?
EDIT
After manipulating my loop iterators (I shortened the number of loops), I now get an informative error:
"ReferenceTable overflow (max=512)"
JNI local reference table summary (512 entries):
509 of Ljava/lang/Class; 164B (3 unique)
2 of Ljava/lang/String; 28B (2 unique)
1 of [Ljava/lang/String; 28B
Memory held directly by tracked refs is 576 bytes
Failed adding to JNI local ref table (has 512 entries)
That "509 of java.lang.class" doesn't look too right to me...how can I optimize my code here?

From that error message, it appears that some bit of native code has called a function that returns a Class object, and has done so 509 times. 507 of those calls returned one particular class.
JNI local references let the GC know that native code is looking at an object, and therefore that object can't be collected even if there are no references to it elsewhere. These local refs are released when the native code returns to the VM. If the native code does a lot of work without returning, it's possible to overflow the local ref table.
You probably just need to add a DeleteLocalRef somewhere. My guess is you need to add one at the end of DrawTile, because of the GetObjectClass call. Better yet, move those GetMethodID calls to a one-time setup function. (They do string searches to find the method, making them not especially quick.)
For more info see JNI Tips.

i think this might be a memory problem. do you release the arrays?
if you get arrays with
(*env)->GetByteArrayElements(env, arr, &isCopy)
you must release the array on the c-side it after each procedure or you will fill your memory till you get over the limit (limit size depends on android version and/or manufacturer but is to my knowledge max 48MB per app)
(*env)->ReleaseByteArrayElements(env, arr, &isCopy, 0);
see here: http://www.iam.ubc.ca/guides/javatut99/native1.1/implementing/array.html
btw, this method does copy the arrays from java to a new memory block in c, you work there and at the end its copied back to java (which memory might have been moved to another location till then). for performance improvement you might look at https://groups.google.com/forum/?fromgroups#!msg/android-ndk/phDP5zqiYY4/BFMw4zTme8IJ

Related

Kotlin chunked and map

I am quite new to all things Android and Kotlin. I am currently working with an Android app from Punch Through:
(Blog: https://punchthrough.com/android-ble-guide/)
(GitHub: https://github.com/PunchThrough/ble-starter-android)
The app connects with a BLE peripheral and allows the user to enter text to send to the peripheral via UART.
I am struggling interpreting what the following code means / does:
with(hexField.text.toString()) {
if (isNotBlank() && isNotEmpty()) {
val bytes = hexToBytes()
ConnectionManager.writeCharacteristic(device, characteristic, bytes)
}
}
Where hexField.text.toString() is the text entered in the EditText field by the user,
and
where hexToBytes() is defined as:
private fun String.hexToBytes() =
this.chunked(2).map { it.toUpperCase(Locale.US).toInt(16).toByte() }.toByteArray()
I have tried this a few times, always entering “111” and have am using Timber() to output the result of bytes. This result varies every time, for example:
[B#2acf801
[B#476814a
[B#e9a70e5
[B#10172a0
So, I assume that only the first three characters are relevant, and somehow there is no end of line / string information.
So perhaps I am only interested in: [B#.......
B# = 0x 5B 42 40
Hex: 5B4240
Dec: 5980736
Bin: 10110110100001001000000
So then I try (and fail) to interpret / breakdown what this code might be doing.
The first thing I struggle with is understanding the order of operation.
Here's my guess....
Given EditText entry, in this case I entered "111"
First:
this.chunked(2)
would produce something like:
"11 and "01"
Second, for each of the two items ("11 and "01"):
it.toUpperCase(Locale.US).toInt(16).toByte()
would produce byte values:
17 and 1
Third:
.map .toByteArray()
Would produce something like:
[1,7,1]
or
[0x01, 0x07, 0x1]
or
[0x0x31, 0x37, 0x31]
So, as you can see, I am getting lost in this!
Can anyone help me deconstruct this code?
Thanks in advance
Garrett
I have tried this a few times, always entering “111” and have am using Timber() to output the result of bytes. This result varies every time
The output when you try to print a ByteArray (or any array on the JVM) doesn't show the contents of the array, but its type and address in memory. This is why you don't get the same result every time.
In order to print an array's contents, use theArray.contentToString() (instead of plain interpolation or .toString()).
Regarding the interpretation of the code, you almost got it right, but there are a few mistakes here and there.
this.chunked(2) on the string "111" would return a list of 2 strings: ["11", "1"] - there is no padding here, just the plain strings with max size of 2.
Then, map takes each of those elements individually and applies the transformation it.toUpperCase(Locale.US).toInt(16).toByte(). This one makes the string uppercase (doesn't change anything for the 1s), and then converts the string into an integer by interpreting it in base 16, and then truncates this integer to a single byte. This part you got right, it transforms "11" into 17 and "1" into 1, but the map {...} operation transforms the list ["11", "1"] into [17, 1], it doesn't take the digits of 17 individually.
Now toByteArray() just converts the List ([17, 1]) into a byte array of the same values, so it's still [17, 1].

Understand BINDER_VM_SIZE in Android source code

In file framework/native/libs/binder/ProcessState.cpp
Why is BINDER_VM_SIZE set to 1M-8k?
#define BINDER_VM_SIZE ((1*1024*1024) - (4096 *2))
It's not this value initially, you can find that(from git commit log) it's first value is
#define BINDER_VM_SIZE (1*1024*1024)
Then someone change this value to
#define BINDER_VM_SIZE ((1*1024*1024) - (4096 *2))
with the following commit message:
Modify the binder to request 1M - 2 pages instead of 1M. The backing
store in the kernel requires a guard page, so 1M allocations fragment
memory very badly. Subtracting a couple of pages so that they fit in
a power of two allows the kernel to make more efficient use of its
virtual address space.
I myself don't fully understand this message,so I just paste it here hope it may help your understanding!

ARM NEON Assembler - usage & understanding

I am new to assembler and NEON programming.
My task is to convert part of an algorithm from C to ARM Assembler using NEON instructions.
The algorithm takes an int32 array, loads different values from this array, does some bitshifting and Xor and writes the result in another array.
Later I will use an array with 64bit values, but for now i just try to rewrite the code.
C Pseudo code:
out_array[index] = shiftSome( in_array[index] ) ^ shiftSome( in_array[index] );
So here are my questions regarding NEON Instructions:
1.) If i load a register like this:
vld1.32 d0, [r1]
will it load only 32Bit from the memory or 2x32Bit to fill the 64Bit Neon D-Register?
2.) How can I access the 2/4/8 (i32, i16, i8) parts of the D-Register?
3.) I am trying to load different values from the array with an offset, but it doesn't
seem to work...what am I doing wrong... here is my code:
(it is an integer array so I´m trying to load for example the 3-element, which should have an offset of 64Bit = 8 Byte)
asm volatile(
"vld1.32 d0, [%0], #8 \n"
"vst1.32 d0, [%1]" : : "r" (a), "r" (out): "d0", "r5");
where "a" is the array and "out" is an pointer to an integer (for debugging).
4.) After I load a value from the array I need to shift it to the right but it doesn't seem to work:
vshr.u32 d0, d0, #24 // C code: x >> 24;
5.) Is it possible to only load 1 Byte in a Neon register so that I don't have to shift/mask something to get only the one Byte i need?
6.) I need to use Inline assembler, but I am not sure what the last line is for:
input list : output list : what is this for?
7.) Do you know any good NEON References with code examples?
The Program should run on an Samsung Galaxy S2, cortex-A9 Processor if that makes any difference. Thanks for the help.
----------------edit-------------------
That is what i found out:
It will always load the full Register (64Bit)
You can use the "vmov" instruction to transfer part of a neon register to an arm register.
The offset should be in an arm register and will be added to the
base address after the memory access.
It is the "clobbered reg list". Every Register that is used and
neither in the input or output list, should be written here.
I can answer most of your questions: (update: clarified "lane" issue)
1) NEON instructions can only load and store entire registers (64-bit, 128-bit) at a time to and from memory. There is a MOV instruction variant that allows single "lanes" to be moved to or from ARM registers.
2) You can use the NEON MOV instruction to affect single lanes. Performance will suffer when doing too many single element operations. NEON instructions benefit application performance by doing parallel operations on vectors (groups of floats/ints).
3) The immediate value offsets in ARM assembly language are bytes, not elements/registers. NEON instructions allow post increment with a register, not immediate value. For normal ARM instructions, your post-increment of 8 will add 8 (bytes) to the source pointer.
4) Shifts in NEON affect all elements of a vector. A shift right of 24 bits using vshr.u32 will shift both 32-bit unsigned longs by 24 bits and throw away the bits that get shifted out.
5) NEON instructions allow moving single elements in and out of normal ARM registers, but don't allow loads or stores from memory directly into "lanes".
6) ?
7) Start here: http://blogs.arm.com/software-enablement/161-coding-for-neon-part-1-load-and-stores/ The ARM site has a good tutorial on NEON.
6) Clobbered registers.
asm(code : output operand list : input operand list : clobber list);
If you are using registers, which had not been passed as operands, you need to inform
the compiler about this. The following code will adjust a value to a multiple of four. It
uses r3 as a scratch register and lets the compiler know about this by specifying r3 in the
clobber list. Furthermore the CPU status flags are modified by the ands instruction.
Adding the pseudo register cc to the clobber list will keep the compiler informed about
this modification as well.
asm (
"ands R3, %1, #3"
"eor %0, %0, r3"
: "=r"(len)
: "0"(len)
: "cc", "r3"
);

Can large String Arrays freeze my program?

I recently created a program that gets medi-large amounts of xml data and converts it into arrays of Strings, then displays the data.
The program works great, but it freezes when it is making the arrays (for around 16 seconds depending on the size).
Is there any way I can optimize my program (Alternatives to string arrays etc.)
3 optimizations that should help:
Threading
If the program freezes it most likely means that you're not using a separate thread to process the large XML file. This means that your app has to wait until this task finishes to respond again.
Instead, create a new thread to process the XML and notify the main thread via a Handler when it's done, or use AsyncTask. This is explained in more detail here.
Data storage
Additionally, a local SQLite database might be more appropriate to store large amounts of data, specially if you don't have to show it all at once. This can be achieved with cursors that are provided by the platform.
Configuration changes
Finally, make sure that your data doesn't have to be reconstructed when a configuration change occurs (such as an orientation change). A persistent SQLite database can help with that, and also these methods.
You can use SAX to process the stream of XML, rather than trying to parse the whole file and generating a DOM in memory.
If you find that you really are using too much memory, and you have a reason to keep the string in memory rather than caching them on disk, there are certainly ways you can reduce the memory requirements. It's a sad fact that Java strings use a lot of space. They require two objects (the string itself and an underlying char array) and use two bytes per char. If your data is mostly 7-bit ASCII, you may be better of leaving it as a UTF-8 encoded byte stream, using 1 byte per character in the typical case.
A very effective scheme is to maintain an array of 32k byte buffers, and append the UTF-8 representation of each new string onto the first empty space in one of those arrays. Your reference to the string becomes a simple integer: PTR = (buffer index * 32k) + (buffer offset). "PTR/32k" yields the index of the desired byte buffer, and "PTR % 32k" yields the location within the buffer. Use either an initial length byte or a null terminator to keep track of how long the string is. When you need to access one of the strings, don't allocate a new String object: unpack it into a mutable StringBuilder or work directly with the UTF-8 byte representation.
The above approach is obviously a lot more work, but can save you between a factor of 2 and 6 in memory usage (depending on the length of your strings). However, you should beware of premature optimization. If your problem is with the processing time to parse your input, or is somewhere else in your program, you could find that you've done a lot of work to fix something that isn't your bottleneck and thus get no improvement at all.

what is Best way to save the large number of Checkboxes state in Android?

I have some 34 checkboxes on one Activity which i have to mark and unmark. and I want to save the status of the each checkbox.
I want this persistently. So should i have a sqlite table or preferences ?
If sqlite table is recommended, then what should be the ideal table structure design?
You could do it either by using SQLite or preferences. Though... what you want to do is kind of simple, so why would you care of creating a table, creating SQliteOpenHelper objects, designing a table, etc. The preferences approach is simpler.
So... what is most important here is how you identify your checkboxes. If you have just 34 static checkboxes (meaning they won't change its order) and they are into an array (which would be ideal), you have it easy.
As you might know, preferences editor does not allow to save arrays. So you have some choices:
Saving each state into a different preference slot (for instance: putBoolean("checkbox2", true); putBoolean("checkbox3", false); ect.)
Save all states into an String: putString("checkboxes_state", "10101011100011010"); this way you will have a String with 34 chars, each char represents a state.
If you want efficiency, you can represent all states with a simple long equals or lower than 17179869183. For instance putLong("checkboxes_state", 17179869183) would mean that all checkboxes are selected (because its binary representation is 1111111111111111111111111111111111). More examples:
12159999103 = 1011010100110010101101110001111111
1 = 0000000000000000000000000000000001, meaning that only the last checkbox is selected.
Edit
With regards to your question of why the last one is more efficient let me briefly explain. The first one implies using 34 preferences slots (actually I don't know how they are stored; hopefully, android team took care of performance). The second approach will use a 34 chars String; so, the minimum size that the String object would have is:
minimum String memory usage (bytes) = 8 * (int) ((34 * 2 + 45) / 8) = 113 bytes
Meaning that a String of that lengthen will take up at least 113 bytes. On the other hand, using just one long will take up 8 bytes only. The less bytes to work with, the faster your app will be (because Android will have to process and save less bytes).

Categories

Resources