I knowingly created the following class to cause out of memory error
public class Test1
{
public static void main(String[] args)
{
StringBuffer sb = new StringBuffer();
while(true)
{
Test1 a = new Test1();
sb.append(a.toString());
}
}
}
As I expected this above class fails with what I wanted…
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
at java.util.Arrays.copyOf(Unknown Source)
at java.lang.AbstractStringBuilder.expandCapacity(Unknown Source)
at java.lang.AbstractStringBuilder.append(Unknown Source)
at java.lang.StringBuffer.append(Unknown Source)
at Test1.main(Test1.java:10)
but this:
public class Test1
{
public static void main(String[] args)
{
StringBuffer sb = new StringBuffer();
while(true)
{
Test1 a = new Test1();
System.out.println(sb.toString());
sb.append(a.toString());
}
}
}
Does not crash. Runs just fine, by printing the object address over and over again on console.
My question is:
What difference a simple SOP made?
Your assumption that there is no
OutOfMemoryErroris likely to be incorrect. It is just massively delayed. Printing a string that is getting bigger and bigger on the out stream takes so much time, that your loop may take an hour to run out of memory.You can double-check this, by printing only every 10th, 100th, 1000th time. You’ll see the error will occur the earlier the less IO you generate. Probably you’ll see a curve like this in
jconsole:As you can see, the heap is slowly but steadily going up. Even if I try to force garbage collection (15:02 and 15:07), I cannot free all memory anymore. But since I’m still only at 5% of my heap, I’ll stop running your code now 🙂