Running out of memory without the OutOfMemoryError

This is actually a reincarnation of a post originally posted in ~2010. The flashback occurred when listening to our engineers cursing at a particularly nasty bug raising its head yesterday. When the cursing stopped, I stepped by to verify my doubts. Lo and behold, I was correct – the mood swing was caused by an app running out of the heap space but dying without the usual OutOfMemoryError symptom.

So let me walk through the case of missing OutOfMemoryError with the same code example I first encountered three years ago. Back then I was using a Windows XP with a mid-2010 JDK 6 installed.

I was playing around with an early release of Plumbr which was supposed to find memory leaks from the application (edit: back then it failed to do pretty much anything besides crashing the JDK). In order to verify this, I wrote a small snippet which I thought would be a good test case for a leak discovery (edit: in reality it is not). I was able to create and launch the following:

class Leak {  
  static List list = new ArrayList();  
  public static void main(String[] args) {  
    for (int i = 0; i >= 0 ;i++) {  
      list.add(i);  
    }  
    System.out.println("I will either reach here or die trying");  
  }  
}

Pretty good for a marketroid, eh? But what do you think running the code displayed to my command prompt:

Option A:

Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
        at java.util.Arrays.copyOf(Arrays.java:2760)
        at java.util.Arrays.copyOf(Arrays.java:2734)
        at java.util.ArrayList.ensureCapacity(ArrayList.java:167)
        at java.util.ArrayList.add(ArrayList.java:351)
        at Leak.main(Leak.java:6)

Option B:

I will either reach here or die trying

Well, as I found out, it doesn’t print out anything, so I was pretty much just stuck to staring the empty command prompt.

java-error-message-missing

As this was two years from my last real Java development experience before being demoted to management, I was out of ammo to troubleshoot the situation. So I took the sample to the hardcore Java hackers who later became known as the founders of Zeroturnaround. For 10 good minutes I managed to have bedazzled look on them as well, before it struck – the memory will be allocated in such a way that there is no room for new OutOfMemoryError() to be created.

If you execute the above with 64MB heap (the default) on Windows XP using a mid 2010 JDK builds, you see a silent failure:

C:\work\snippets\leak java -Xmx64m Leak
C:\work\snippets\leak

But if you increase (well actually modify) the heap size a bit, you will encounter a more familiar situation:

C:\work\snippets\leak java -Xmx65m Leak
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
        at java.util.Arrays.copyOf(Arrays.java:2760)
        at java.util.Arrays.copyOf(Arrays.java:2734)
        at java.util.ArrayList.ensureCapacity(ArrayList.java:167)
        at java.util.ArrayList.add(ArrayList.java:351)
        at Leak.main(Leak.java:6)
C:\work\snippets\leak

Moral of the story? I can only recommend to upgrade to a more modern release – no matter which configuration I tried, I failed to recreate the situation using the JDK 7 builds I had on my Mac today. But looking at the statistics about popular Java runtime configurations, you see a staggering amount of JDK deployments dating back to pre-2010 releases, meaning that the problem is still out there forcing developers to pull crazy all-nighters trying to figure out the source of the problem without any hints from the stacktrace to support them.

Anyhow, backing the engineering team with my extensive knowledge about JDK 6 internals I went ahead and revived the post from the long-forgotten blog I used to contribute back then.
 

Related Whitepaper:

Functional Programming in Java: Harnessing the Power of Java 8 Lambda Expressions

Get ready to program in a whole new way!

Functional Programming in Java will help you quickly get on top of the new, essential Java 8 language features and the functional style that will change and improve your code. This short, targeted book will help you make the paradigm shift from the old imperative way to a less error-prone, more elegant, and concise coding style that’s also a breeze to parallelize. You’ll explore the syntax and semantics of lambda expressions, method and constructor references, and functional interfaces. You’ll design and write applications better using the new standards in Java 8 and the JDK.

Get it Now!  

Leave a Reply


1 × seven =



Java Code Geeks and all content copyright © 2010-2014, Exelixis Media Ltd | Terms of Use
All trademarks and registered trademarks appearing on Java Code Geeks are the property of their respective owners.
Java is a trademark or registered trademark of Oracle Corporation in the United States and other countries.
Java Code Geeks is not connected to Oracle Corporation and is not sponsored by Oracle Corporation.

Sign up for our Newsletter

15,153 insiders are already enjoying weekly updates and complimentary whitepapers! Join them now to gain exclusive access to the latest news in the Java world, as well as insights about Android, Scala, Groovy and other related technologies.

As an extra bonus, by joining you will get our brand new e-books, published by Java Code Geeks and their JCG partners for your reading pleasure! Enter your info and stay on top of things,

  • Fresh trends
  • Cases and examples
  • Research and insights
  • Two complimentary e-books