Re: [android-developers] Wierd memory leak
On Thursday, October 7, 2010, DanH wrote: > Yep, substring MAY (or may not) decide to avoid copying the characters > and simply keep a reference to the char array in the source String. A > smart substring implementation wouldn't do this if the result string > were quite short or the source string quite long, but apparently the > Android implementation isn't that smart. It's a very reasonable behaviour of String class when we take into account that String is immutable and very often Strings are responsible for big chunks of memory allocation. Behaviour of String.substring() makes therefore sense in some(most?) situations. Any other behaviour could cause equally puzzling results in other situations. Another important thing to take into account is that String behaviour is imposed on JVM level (at least Sun's JVM but Dalvik deriving from Apache Harmony will most likely implement similar strategies). Fault lies in details like these not being communicated well enough in the documentation. > > The same thing may occur if you do "new String(someOtherString)". > > There's probably no guaranteed way to prevent this from happening, > unless you somehow use a char array as an intermediate value. > > On Oct 6, 1:50 pm, Alex 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 someStringList = new ArrayList(1000); >> for (int i=0; i<1000; i++) { >> String someBigString = new String(new char[10]); >> 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 someStringList = new ArrayList(1000); >> for (int i=0; i<1000; i++) { >> String someBigString = new String(new char[10]); >> 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 -- Daniel Drozdzewski -- 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
Re: [android-developers] Wierd memory leak
On Thursday, October 7, 2010, DanH wrote: > Yep, substring MAY (or may not) decide to avoid copying the characters > and simply keep a reference to the char array in the source String. A > smart substring implementation wouldn't do this if the result string > were quite short or the source string quite long, but apparently the > Android implementation isn't that smart. It's a very reasonable behaviour of String class when we take into account that String is immutable and very often Strings are responsible for big chunks of memory allocation. Behaviour of String.substring() makes therefore sense in some(most?) situations. Any other behaviour could cause equally puzzling results in other situations. Another important thing to take into account is that String behaviour is imposed on JVM level (at least Sun's JVM but Dalvik deriving from Apache Harmony will most likely implement similar strategies). Fault lies in details like these not being communicated well enough in the documentation. > > The same thing may occur if you do "new String(someOtherString)". > > There's probably no guaranteed way to prevent this from happening, > unless you somehow use a char array as an intermediate value. > > On Oct 6, 1:50 pm, Alex 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 someStringList = new ArrayList(1000); >> for (int i=0; i<1000; i++) { >> String someBigString = new String(new char[10]); >> 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 someStringList = new ArrayList(1000); >> for (int i=0; i<1000; i++) { >> String someBigString = new String(new char[10]); >> 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 -- Daniel Drozdzewski -- 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
Re: [android-developers] Wierd memory leak
On Thursday, October 7, 2010, DanH wrote: > Yep, substring MAY (or may not) decide to avoid copying the characters > and simply keep a reference to the char array in the source String. A > smart substring implementation wouldn't do this if the result string > were quite short or the source string quite long, but apparently the > Android implementation isn't that smart. It's a very reasonable behaviour of String class when we take into account that String is immutable and very often Strings are responsible for big chunks of memory allocation. Behaviour of String.substring() makes therefore sense in some(most?) situations. Any other behaviour could cause equally puzzling results in other situations. Another important thing to take into account is that String behaviour is imposed on JVM level (at least Sun's JVM but Dalvik deriving from Apache Harmony will most likely implement similar strategies). Fault lies in details like these not being communicated well enough in the documentation. > > The same thing may occur if you do "new String(someOtherString)". > > There's probably no guaranteed way to prevent this from happening, > unless you somehow use a char array as an intermediate value. > > On Oct 6, 1:50 pm, Alex 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 someStringList = new ArrayList(1000); >> for (int i=0; i<1000; i++) { >> String someBigString = new String(new char[10]); >> 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 someStringList = new ArrayList(1000); >> for (int i=0; i<1000; i++) { >> String someBigString = new String(new char[10]); >> 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 -- Daniel Drozdzewski -- 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