Strings are wrappers around a char[]; String.substring will create a
new String object with the *same* char[] from the original String.
Your first snippet causes OutOfMemory because you're retaining the
100000 char Strings in someStringList even when you call substring.  I
don't have the Android implementation of String in front of me but I
believe it's similar to the Sun implementation which merely passes the
char[] to the new String.

Looking at the Javadocs for Android's String.substring, I must admit
it could be easily misunderstood that a new String with new backing
char[] is created.

Your second snippet does not cause OutOfMemoryError because of the
String concatenation.  String concatenation creates a new String with
a new backing char[].  The original char[100000] is garbage collected
in that case.

If you need the first char of each large String you could just create
an ArrayList<Character> and just store String.charAt(0).  If you need
some range of the large String that's greater than one char, maybe you
can create a StringBuilder/StringBuffer and append the substring to
that, then store the toString() of that into your ArrayList.

For example:

String someBigString = new String(new char[100000]);
someStringList.add(new StringBuilder(someBigString.substring(0,
1)).toString());

There's probably a better way to do this but I just got home from work
and I'm not quite in a Java thinking mood. :-P

Hope this helps.

  Ernest Woo
  Woo Games
  http://www.woogames.com

On Oct 6, 2:50 pm, Alex <a...@appfactory.at> wrote:
> Hi everybody!
> First of all, sorry for my bad english ;-)
>
> After several hours of searching for the cause of a OutOfMemoryError,
> I found a wierd problem with Strings. To keep it simple, trimmed it
> down to something like this:
>
> ArrayList<String> someStringList = new ArrayList<String>(1000);
> for (int i=0; i<1000; i++) {
>     String someBigString = new String(new char[100000]);
>     String someSmallString = someBigString.substring(0,1);
>     someStringList.add(someSmallString);
>
> }
>
> OK, it's not very useful and even though it's a big string, I would
> expect it to work properly, because only one char is stored in the
> list. But in fact, heap is growing rapidly and OutOfMemoryError
> exception will be thrown in 2,3 seconds. And I can't imagin why.
>
> AND NOW the interessting part, a little workaround:
>
> ArrayList<String> someStringList = new ArrayList<String>(1000);
> for (int i=0; i<1000; i++) {
>     String someBigString = new String(new char[100000]);
>     String someSmallString = someBigString.substring(0,1);
>     someStringList.add(someSmallString + "BUGFIX");
>
> }
>
> WTF? Why is this now working?
> The only difference is the concatenated string (someSmallString +
> "BUGFIX")! And as originally expected, with this workaround nearly no
> memory will be used ...
>
> Any ideas? I would appreciate it very much, if someone could give me
> hint. Maybe I'm missing something basic here?

-- 
You received this message because you are subscribed to the Google
Groups "Android Developers" group.
To post to this group, send email to android-developers@googlegroups.com
To unsubscribe from this group, send email to
android-developers+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/android-developers?hl=en

Reply via email to