I am programming in Kotlin via Android Studio 3.1.3. I created an array of type Long that was apparently too large to compile. After playing around with it for a while, I found that the maximum size array I could get to compile contained 8,207 elements. An array with 8,208 or more elements caused a compilation error. There are 350 lines of elements in the array, which contains prime numbers in numerical order. Two questions:
Does anyone have any idea why this limit would exist? 8,208 is (2^13 + 2^4), but that seems like an odd tipping point. So, I doubt that is the reason for the limitation.
Is there any way to increase the allowed size of the array?
Note: On the Android forum, it was suggested that I use ArrayList instead of ArrayLong. I appreciate that suggestion and intend to try it, but the limitation on a Long Array still seems odd to me. If anyone has a more elegant solution or an explanation for the limit, I would love to hear it! Thank you for your time.
So, what you're trying to do is something like:
var a = longArrayOf(1,2,3,4,5,6,7,8...)
There's a limitation by JVM. Maximum size of method is 64K.
If you decompile your code, you'll receive something like that for each element in the array:
DUP
SIPUSH 8206
LDC 8207
LASTORE
And that's where you hit the limit.
Related
My app uses a proprietary implementation of Canny edge detection based on RenderScript. I tested this on numerous devices with various APIs and it worked very reliably. Now I got the new Samsung S7 working on API23. Here (and only here) I encountered a rather ugly problem. Some of the edge pictures are studded with thousands of artifacts that stem from the Magnitude gradient calculation kernel and are NOT based on actual image information. After trying with all kind of TargetAPIs, taking renderscript.support.mode on and off, etc. I finally found that the problem only arises, when the RenderScript (and Script) instances are used for the second or more times. It does not arise when using them for the first time.
For efficiency reasons I created the RenderScript and Script instances only once in the onCreate method of MainActivity and used it repeatedly thereafter. Of course I don't like to change that.
Does anyone have a solution of this problem? Thanks.
UPDATE: Crazy things are going on here. It seems that freshly created Allocations are NOT empty from the outset! When running:
Type.Builder typeUCHAR1 = new Type.Builder(rs, Element.U8(rs));
typeUCHAR1.setX(width).setY(height);
Allocation alloc = Allocation.createTyped(rs, typeUCHAR1.create());
byte se[] = new byte[width*height];
alloc.copyTo(se);
for (int i=0;i<width*height;i++){
if (se[i]!=0){
Log.e("content: ", String.valueOf(se[i]));
}
}
... the byte Array se is full of funny numbers.... HELP! Any idea, what is going on here?
UPDATE2: I stumbled over my own ignorance here - and really don't deserve a point for this masterpiece.... However, to my defense I must say that the problem was slightly more subtle that it appears here. The context was, that I needed to assign a global allocation (Byte/U8) which initially should be empty (i.e. zero) and then, within the kernel getting partially set to 1 (only where the edges are) via rsSetElementAt_uchar(). Since this worked for many months, I was not aware anymore of the fact, that I didn't explicitely assign the zeros in this allocation.... This only had consequences in API 23, so maybe this can help others not to fall into this trap.... So, note: other than numerical Arrays that are filled with 0 (as by Java default), Allocations cannot assumed to be full of zeros at initiation. Thanks, Sakridge.
Allocation data for primitive types (non-struct/object) is not initialized by default when an Allocation is created unless passed a bitmap using the createFromBitmap api. If you are expecting this then possibly you have a bug in your app which is not exposed when the driver initializes to 0s. It would help if you can post example code which reproduces the problem.
Initialize your allocations by copying from a bitmap or Java array.
I need to modify a so inside an Android APK.
The task is to rename the dynamic symbols in side the so (which is the function name).
For example, change from Java_com_example_abc_.... to Java_com_yahoo_zzz_....
I try to use WinHex directly search and replace text words, the apk startup error.
Seems like the .hash section also needs to be updated, but i do not know how to update the .hash section.
My question is what is the correct or preferable way to rename the dynamic Symbol?
I heave been stuck for 3 days, please help me, thank you very much!
Found a post might related, but he didn't gave the alternative solution.
https://sourceware.org/ml/binutils/2006-03/msg00266.html
I heave been stuck for 3 days, please help me,
What you are trying to achieve is effectively impossible.
ELF files have complicated internal structure, and what you want to do requires that you break it up and re-assemble the parts. An analogy would be to break an Intel CPU into transistors and re-assemble an AMD CPU from them.
Found a post might related
It is related. Quote:
Basically it does the following:
loop over .dynsym and re-create .dynstr
re-create the .hash table from scratch
calculate new lma/vma, new memory layout (.dynstr size changed!)
fix the contents of .dynamic, according to the new layout
fix .rel.dyn
fix .rel.plt
fix .dynsym again
write out the new section contents
In copy_section: exclude the rewritten sections from being copyied.
Currently it seems to create a syntactically valid ELF file, but as
the distance between .plt and .got changes, the relative addressing in
.plt is broken. Additionally the .got has to be fixed again.
So the author managed to glue together something that looks like an AMD CPU, but which doesn't work.
Sure, you can spend another 2 weeks to understand what the author did, and then another 3 weeks to fix the remaining broken pieces. And after that, you may get something that kind of sometimes works.
Your time is likely better spent elsewhere.
Have a look at LIEF, but try to keep them the same length
native_lib = 'my_native_lib.so'
lib = lief.parse(native_lib)
for x in lib.exported_symbols:
if x.name == 'Java_com_example_abc':
x.name = 'Java_com_foobarr_zzz'
lib.write(native_lib) # overwrite
The ability to change names in shared libraries was added in Patchelf: https://github.com/NixOS/patchelf/commit/da035d6acee1e5a608aafe5f6572a67609b0198a
It should be available in the next release (after 0.17.2). Meanwhile you can build the tool following the instructions in https://github.com/NixOS/patchelf#compiling-and-testing
To use it, create a map file with two names (old and new) per line, and invoke Patchelf with:
$ patchelf --output libPatched.so --rename-dynamic-symbols map_file libOriginal.so
Please provide feedback if you find issues. Thanks!
I want to compare two XML files, they are the same as each other. i have one of them in local storage and using bufferReader i put it on String and i get the other one from server and again put it into the String! then i Print the content of them and they are actually the same! nothing differs even spaces!! but when i compare them ( 2 strings) using equalsIgnoreCase they are not equal and always goes to else! which means they are not equal!
can anybody help on this? if no way to compare like this so how can i compare them?
I think it happens due to formatting issue.
You can use XMLUnit to resolve the issue.
XMLUnit will help you in
The differences between two pieces of XML
The outcome of transforming a piece of XML using XSLT
The evaluation of an XPath expression on a piece of XML
The validity of a piece of XML
Individual nodes in a piece of XML that are exposed by DOM Traversal
Did you tried string1.equals(string2)
In a game I need to keeps tabs of which of my pooled sprites are in use. When "active" multiple sprites at once I want to transfer them from my passivePool to activePool both of which are immutable HashSets (ok, i'll be creating new sets each time to be exact). So my basic idea is to along the lines of:
activePool ++= passivePool.take(5)
passivePool = passivePool.drop(5)
but reading the scala documentation I'm guessing that the 5 that I take might be different that the 5 I then drop. Which is definitely not what I want. I could also say something like:
val moved = passivePool.take(5)
activePool ++= moved
passivePool --= moved
but as this is something I need to do pretty much every frame in realtime on a limited device (Android phone) I guess this would be much slower as I will have to search one by one each of the moved sprites from the passivePool.
Any clever solutions? Or am I missing something basic? Remember the efficiency is a primary concern here. And I can't use Lists instead of Sets because I also need random-access removal of sprites from activePools when the sprites are destroyed in the game.
There's nothing like benchmarking for getting answers to these questions. Let's take 100 sets of size 1000 and drop them 5 at a time until they're empty, and see how long it takes.
passivePool.take(5); passivePool.drop(5) // 2.5 s
passivePool.splitAt(5) // 2.4 s
val a = passivePool.take(5); passivePool --= a // 0.042 s
repeat(5){ val a = passivePool.head; passivePool -= a } // 0.020 s
What is going on?
The reason things work this way is that immutable.HashSet is built as a hash trie with optimized (effectively O(1)) add and remove operations, but many of the other methods are not re-implemented; instead, they are inherited from collections that don't support add/remove and therefore can't get the efficient methods for free. They therefore mostly rebuild the entire hash set from scratch. Unless your hash set has only a handful of elements in it, this is bad idea. (In contrast to the 50-100x slowdown with sets of size 1000, a set of size 100 has "only" a 6-10x slowdown....)
So, bottom line: until the library is improved, do it the "inefficient" way. You'll be vastly faster.
I think there may be some mileage in using splitAt here, which will give you back both the five sprites to move and the trimmed pool in a single method invocation:
val (moved, newPassivePool) = passivePool.splitAt(5)
activePool ++= moved
passivePool = newPassivePool
Bonus points if you can assign directly back to passivePool on the first line, though I don't think it's possible in a short example where you're defining the new variable moved as well.
I am facing the problem of low memory. Low memory:no more background process And here is the scenario.
I am using a list which gets its data from a string array, it has a custom background, Clicking on item, the list gets another string array to display as second or third level. Information for three levels written in database.
After third level, there are two more levels for which data is going to be fetched from web services,
And that causes the low memory error.
How can I get rid of the solution?
Edit : After having some digging I found that the GC is trying to (kill or) restart in case of its already crashed com.android.inputmethod.latin/.latinIMEservice. One notable point is that the application is translated in french and italian, but this screen does not have any text for translation, does this information helps??
Edit 2: After a detailed study of traceview I found that all the text views have custom fonts applied in it. (There is a call of TypeFace.createFromAsset()) that IMO causes the crashes.
And the problem lies in the fact that I have to keep the fonts....
can It be possible to avoid crash and have the fonts?? (Because i think the answer is no: But still waiting for some opinions)
Edit 3 : After removing the custom fonts the performance of application is much better. Hence I can suspect the font is the only culprit here. And that's why I am editing question. The font I use is helvetica.
Can using external fonts cause application to crash or running out of memory? If yes can you describe the cause in more detail??
Thanks
If you are using code similar to:
Typeface font = Typeface.createFromAsset(getContext().getAssets(),
"fonts/Helvetica.ttf");
try making "font" a global variable so it only gets loaded once. Otherwise it can be loaded repeatedly, quickly consuming memory. See this message for a little more detail
Well, question is a bit unclear to have answered:
After each level - do you switch/start to another Activity? If so you shouldn't keep anywhere references to old activity. Otherwise it could trigger OOM problems
I suppose you're fetching data using some kind of Cursor alike object. Cursor's are very memory-consuming objects, so you'd better not only just close Cursor's, but you should also call Cursor.deactivate()