|
Post by kallin on Jul 30, 2008 17:38:12 GMT -5
Hey guys,
I decided to try profiling the most basic j2me app using a canvas with an image to see what's using up the memory.
I noticed four offenders:
char[] (com.sun.midp.midlet.Selector.run() ) String (same place) StringBuffer (same place) VectorEnumerator(com.sun.midp.lcdui.DefaulteventHandler$QueuedEventHandler.run() )
It appears there's a fair bit of object creation going on outside my control, which inevitably leads to frequent garbage collection.
Has anyone looked into this before?
|
|
|
Post by kallin on Jul 30, 2008 17:46:09 GMT -5
Quick update:
I found that by eliminating any javax.microedition.lcdui.Graphics.drawString() calls I was able to eliminate the allocation of the char[], String, and StringBuffers.
I can't figure out any way to stop the VectorEnumerators though. There is nothing in my paint routine now.
|
|
|
Post by Adam Schmelzle on Jul 30, 2008 18:01:12 GMT -5
Can't do anything about the enumerator. In the older WTK's, it didn't show up in the profiler, but in the new ones it does. The devices likely don't have this issue either. That's just Sun being overl OO-ish in their emulator. You don't need to worry about it, but it does add annoying stats to the profiling.
|
|
|
Post by kallin on Jul 30, 2008 18:11:25 GMT -5
Ahh great thanks Adam.
Do you know if the issue with string allocation is just an emulator issue as well? The strings in my test app are all static-final, so I know it's not me. Graphics.drawstring() seems to do it.
I guess what I really need to do is find a way to profile this in real hardware. All I can think to do right now is Runtime.getRuntime().freeMemory() . It would be great if there were a JAD that could load another JAD and act as a profiler on the real machine or something like that. Have you ever seen anything that could offer profiling on the real hardware?
|
|
|
Post by Adam Schmelzle on Jul 30, 2008 19:04:24 GMT -5
drawstring is a hog, even on devices. Use the char[] version instead, it helps a lot.
|
|
|
Post by kallin on Jul 31, 2008 9:34:59 GMT -5
Yeah you're right, no extra allocation with chars.
Of course it's not much fun appending chars together using System.arraycopy... Maybe i'll just use a global stringbuffer for any work like that.
|
|
|
Post by Adam Schmelzle on Jul 31, 2008 10:34:46 GMT -5
What I do is keep one gigantic char[] in memory for all my strings. Along with that, I have an array that keeps track of the start indices, one for end indices, one for string length(# chars), and one with the visual width of the string when displayed on screen.
To use this data, I have a funtion i[nt drawStr(Graphics g, int stringIndex, int x, int y, int orientation)]; The return is the visual width used when drawing, so that I can do stuff like this...
int currentX = 0; int currentY = 0; currentX += drawStr(g, STR_GAMEOVER, currentX, currentY, Graphics.TOP | Graphics.LEFT); currentX += SPACE_WIDTH; currentX += drawStr(g, STR_LOSER, currentX, currentY, Graphics.TOP | Graphics.LEFT);
|
|