I am a newcomer to the forums here and Java novice. I have searched around quite a bit and will continue to do so, but thought I'd put this question to the user community in hopes someone can point out an obvious mistake I may be making...
I have a java class that executes a series of file loads, and as these file loads are executed the program uses a large amount of heap memory, eventually causing a failure with the java.lang.OutOfMemoryError. I can increase the JVM memory with -Xmx1024m (about the largest I can go on the machine running the program), and in most cases this will allow the program to run to completion. However, when given a large input, 1024m is still proving to be insufficient, and I'm pretty sure my code could use a few obvious improvements to allow for less memory consumption.
Using JProbe profiler, it appears my program consumes (and doesn't release) a large amount of memory during the following statement, which writes to a CSV file. ps2 is a PrintStream object that I am declaring with the autoflush = true option (which isn't seeming to help). Basically this nasty code is writing my CSV formatted file, and this statement can be iterated in upwards of 40K times. I've also tried explicitly nulling the ps2 object and forcing a garbage collection with gc() after all rows have been written, but isn't helping either. Any suggestions?
If you google StringBuffer vs String Java it leads you to this article, which will explain that there is actually a significant difference in Performance:
Thank you very much for your suggestions. I seem to have corrected the memory consumption issue, and I'm afraid the solution was quite simple: 1) re-use 1 printStream object throughout the code, and more importantly 2) null out my query result objects after I am finished with each. 2) freed up a ton of memory.
> PLEASE USE THE JAVA TAGS AND PROPER INDENTITION (SHOWN ON > YOUR RIGHT-HAND SIDE WHEN POSTING. > > Depending on how many times you are looping, try using a > StringBuffer for concatenation as opposed to a String with > the + operator. > > E.g. > > instead of: > >
> > then go: > > buf.toString(); > > when you want to use it. > > It is much more efficient, not sure how drastically this > will reduce your memory consumption though (but give that > a shot).
Actually in modern versions of Javac (1.4+, maybe even in 1.3), the two ways of concatenating Strings compile to basically the same bytecodes. The compiler uses a StringBuffer under the hood. In 1.5 and beyond, the + version may even be faster as the compiler will use a StringBuilder instead of a StringBuffer.
Even if this were an old version of Java where a new String was created on each concat, this should not cause an OOME because the Strings should be available for GC as soon as the next concat call completes.
> Thank you very much for your suggestions. I seem to have > corrected the memory consumption issue, and I'm afraid the > solution was quite simple: 1) re-use 1 printStream object > throughout the code, and more importantly 2) null out my > query result objects after I am finished with each. 2) > freed up a ton of memory. > > Thanks again....
One thing that you can do with the code you posted is change it to something like this: