views:

559

answers:

3

My code is doing things like this:

for(SomeObject so : someObjects)
{
  Blah b = so;
  NewObject n = dao.GetNO(b.23);
}

i.e. it is creating a new variable inside the for loop on each iteration.

Could this be the cause of the out of memory issue?

The error reported by Netbeans:

Caused by: java.lang.OutOfMemoryError: Java heap space
        at java.lang.StringCoding$StringDecoder.decode(StringCoding.java:133)
        at java.lang.StringCoding.decode(StringCoding.java:173)
        at java.lang.String.<init>(String.java:443)
        at java.lang.String.<init>(String.java:515)
        at com.gargoylesoftware.htmlunit.WebResponseImpl.getContentAsString(WebResponseImpl.java:215)
        at com.gargoylesoftware.htmlunit.WebResponseImpl.getContentAsString(WebResponseImpl.java:205)

Upate This is a java console application, and the entire app runs a in forloop basically.

+1  A: 

You're running out of memory when you're trying to hold on to more objects that will fit into memory. If you're creating an object in a loop it will get GarbageCollected as soon as it goes out of scope.

So if you write

for (.....){
   Object o = new Object();
}

-you're never holding more than one instance of o, so it's not going to be the cause (unless you're storing a reference to them somewhere else, for example by putting them in a map outside the loop scope).

You need to look for a place in the code that's holding on to more references. From your posting it's impossible to tell more.

BTW, you might also consider bumping up the amount of memory you're using in your JVM with -Xmx and -Xms options (type "java -X" for more information), which might get it to run, although it won't help you find a mistake. Since you're running inside netbeans you also may be running out of memory because it's running in the same JVM. I don't use netbeans, but you could check and see if netbeans allows you to fork a new process to run your program (so that you're not trying to run while sharing memory with netbeans, which is not small), or try running directly on the command line.

Steve B.
A: 

Most likely thing is that you're accidentally holding onto some objects somewhere. Usual culprits are poorly implemented caches, or their functional equivalent.

Another possibility is that you simply don't have enough memory for whatever you're doing. Java starts (at least Sun's does by default) with a 64 MB of heap. You can change this with the -xmx parameter.

Finally, I recall in 1.4.X days that you could cause an OutOfMemoryError if enough time (as a percentage of total process cpu time) was spent garbage collection (for some particular garbage collector implementation). The cutoff was in the 90% range. I've seen this once in nearly a decade, and it was a really neurotic use case. Its probably not this, but it could be. I'm not sure that this behavior persists in modern Java.

My advise: inspect the implementation of dao.GetNO(...) and see whether it creates any objects as a side effect, and what their lifetimes are.

Kevin Montrose
+4  A: 

Are you running with Java 5 or greater, or one of the legacy JVM's? You can try to track down the cause of your OOM by arming your Java command line with -XX:+HeapDumpOnOutOfMemory or attaching to your process with JConsole and requesting a heap dump. You can then use the Eclipse MAT tool to open the dump and view the object graph to see whose holding onto the objects in your program. MAT has a view to see those objects that dominate the object graph - so it becomes extremely clear what exactly is leaking. Looking at the stack trace is not helpful, and can be misleading because a leak in one location of the program can cause a failed allocation somewhere else.

Amir Afghani
This seems like overkill given the scope of the problem described.
Steve B.
Really? Knowing what objects are occupying the heap after I see an OOM is not overkill for me.
Amir Afghani