k700i: out of memory ?!?

i have problems getting my midlet working on the k700i. the phone says it’s out of memory after a long loading time.
after a few tries i identificated the bad class:
its a class which automatically formatts some text passages.
it only uses local variables and only sends a string array back.

the formatting sequence is as follows:


MidletConstructor
{
         String txt1[] = textFormatter.format(sometextstring);
         String txt2[] = textFormatter.format(anotherString);
         etc..
}

i call this method several times (about 10 times). if i only format the first string, all is ok. another one lets the memory explode (says the phone).
but the class isnt really on my focus cause i tracked the whole thing with the memory monitor (like you can guess the midlet runs flawlessly on emulators).

the k700i seems to have a heap of 100k. at the time, where the first string gets formatted the phone takes 35k.
when the whole game is loaded and main menu gets displayed the heap is up to 53k.

so im not even nearly scratching the limit.
is there any known issue which can cause this error ?

I don’t know about known issues in the k700i. But is it possible that your text formatter class uses a very large amount of memory for temporary variables, which aren’t in use afterwards? That way you could have a high peak memory usage even though it’s low again afterwards.

Another possibility would be that the second string you pass to the text formatter triggers a bug that uses up much more memory than it should (but still not enough to trouble the emulator).

Does your text formatter use String.substring(…)?

substring does not copy the original String, it simply references a subset of the parents char [].

therefor, if you have a huge String, grab a small portion of it (using substring), then discard the original huge String.
The original char [] will not be garbage collected.

Incidentally, the K700 has 512kb of heap, which will expand to upto 1.5mb upon demand.

i hop you have the patience to help me with my now changed problem. i worked on my method to use less memory. it seems to be solved but another strange error occurs. before
i paste the method, i want to share my experiments:

first, my method works on all tested phone without any exceptions or errors. only the k700 and the t610 have problems (but in a slightly different way).

like you will see the core of the method is a tokenizer which goes through all characters and adds their width. if this width
is larger that a given size the character index returns to the last space-character and breaks into a new line.
the problem lies within the variable tokenIndex and its influence to the loop.
if i disable the addition of the char’s width (that can happen in many lines) the midlet starts. if i dont do so, on k700 first the constructor loaded without an end.
then i noticed that i used special characters like ‘ü’ and ‘ß’ in my sentences.
after replacing them i only get an application error ;D

i used lots of debug outputs and proofed that no index is used out of the string’s boundaries (getCharAt(), substring()).
and my main argument: the identical midlet runs e.g. on my motorola v525.

now for those brave of you, the code:


/** 
     * Tries to break a long line of text into several shorter ones, so that
     *  the width of the produced lines is never wider that <i>areaWidth</i>.
     *  The width of the strings is calculated by the width of each appearing
     *  character using the charWidth() method of the given font object.
     * 
     *  TODO: method fails if the string has no breaking points (spaces) and
     *        is larger than areaWidth
     *  */
    public String[] tokenizeText(String s, Font font, int areaWidth) 
    {
        // valid string ?
        if( s == null )      return null;
        System.out.println("\n\n **** TOKENIZING **** ");
        System.out.println("tokenize: "+s);
        System.out.println("length of string "+s.length());
        
        // contains the new formatted text block, each entry means a text row
        Vector newOrder = new Vector();
        // the string array which is returned by this method as result
        String resultStrings[];
                
        int startToken = 0, lastSpace = 0;
        int currentRowWidth  = 0;
        int row = 0;
        
        
        // checking all characters
        for(int tokenIndex=0; tokenIndex<s.length(); tokenIndex++)
        {
            currentRowWidth+=font.charWidth(s.charAt(tokenIndex));
         
            // marking a space as return point for line break
            if(s.charAt(tokenIndex) == ' ')
                lastSpace = tokenIndex; 
           
            // if the width of all checked chars exeeds the boundaries
            // return to the last marking point and access new line (next array field)
            if(currentRowWidth >= areaWidth)
            {
                // creating one row of text, fitting into boundaries
                newOrder.addElement( s.substring(startToken, lastSpace) );
                
                // marking start (and end) of characters to convert
                startToken = lastSpace+1;
                tokenIndex = lastSpace+1;
                
                currentRowWidth = 0;
            }
            
        }
        
        // formatting the remaining chars to row
        newOrder.addElement( s.substring(startToken) );
        
        // convert vector of strings into string array
        resultStrings = new String[newOrder.size()];
        for(int i=0; i<newOrder.size(); i++)
            resultStrings[i] = (String)newOrder.elementAt(i);

        return resultStrings;
        
    }