It seems no one has reported similar situations... I have absolutely no idea what happened...
I have a StringBuilder
of size 8Mb to process a large String result
. I am trying to reuse the StringBuilder
. I thought setting length = 0 will just reset the counter and not allocate new memory?
try {
//result.length() around 4Mb
StringBuilder sBuilder = new StringBuilder(result.length());
result = DoSomethingToResult1(sBuilder, result); //shrink result a bit using replaceAll
try {
sssBuilder.setLength(0);
result = DoSomethingToResult2(sBuilder, result); //shrink result further using replaceAll
} catch (OutOfMemoryError e) {
Log.d(TAG, "Out of Memory on 2");
}
try {
sBuilder.setLength(0); //OutOfMemory thrown here.
result = DoSomethingToResult3(sBuilder, result); //shrink result even further using replaceAll
} catch (OutOfMemoryError e) {
Log.d(TAG, "Out of Memory on 3");
}
} catch (OutOfMemoryError e) {
Log.d(TAG, "Cannot create sBuilder");
}
The process usually dies on the second setLength(0)
, sometimes dies on the first setLength(0)
, but it can always create the sBuilder
in the beginning.
In DoSomethingToResult
, I split result
into chunk of 100Kb size and append to sBuilder
one by one, returning sBuilder.toString(). So problem does not come from replaceAll
. And since it passed the first process, I don't think the toString()
is the problem either.
I tried:
sBuilder.setLength(0);
System.gc();
try{
Thread.sleep(1000);
}catch(Exception e){};
or
System.gc();
try{
Thread.sleep(1000);
}catch(Exception e){};
sBuilder.setLength(0);
Both failed.
Log output:
E/dalvikvm-heap(27130): Out of memory on a 8723792-byte allocation.
I/dalvikvm(27130): "AsyncTask #1" prio=5 tid=11 RUNNABLE
I/dalvikvm(27130): | group="main" sCount=0 dsCount=0 obj=0x42036a18 self=0x51c2eb08
I/dalvikvm(27130): | sysTid=27151 nice=10 sched=0/0 cgrp=apps/bg_non_interactive handle=1371731208
I/dalvikvm(27130): | schedstat=( 0 0 0 ) utm=197 stm=17 core=1
I/dalvikvm(27130): at java.lang.AbstractStringBuilder.setLength(AbstractStringBuilder.java:~567)
I/dalvikvm(27130): at java.lang.StringBuilder.setLength(StringBuilder.java:44)