CFSAVECONTENT generates JAVA heap space error
Posted At : January 27, 2008 4:53 PM
| Posted By : Dave
Related Categories:
ColdFusion
I found this little gem while working on some code for my upcoming presentation to the CF online user group. I was working to crate a text file that contained a million lines of text. The code ran perfectly while doing test runs generating only 10 lines. When I ran it to create the million lines it failed out.
Here is the code I wrote:
<CFSAVECONTENT VARIABLE="theRes">
<CFLOOP INDEX="i" FROM="1" TO="1000000"><CFOUTPUT>#i#</CFOUTPUT>: Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Donec libero. Suspendisse bibendum. Cras id urna. Morbi tincidunt, orci ac convallis aliquam, lectus turpis varius lorem, eu posuere nunc justo tempus leo. Donec mattis, purus nec placerat bibendum, dui pede condimentum odio, ac blandit ante orci ut diam.
</CFLOOP>
</CFSAVECONTENT>
</CFPROCESSINGDIRECTIVE>
<CFFILE ACTION="WRITE" FILE="#expandPath('.')#\textfile.txt" OUTPUT="#theRes#" NAMECONFLICT="OVERWRITE">
The error was not even a CF error message but a JRun servlet error.
java.lang.OutOfMemoryError: Java heap space
javax.servlet.ServletException: ROOT CAUSE:
java.lang.OutOfMemoryError: Java heap space
It appears that there may be a memory max to CFSAVECONTENT. So, I got curious and starting playing with the code. After a bunch of trial and error I was able to figure out the max loop count I could run without error was 294712. This generated a 92mb text file. So, without figuring it out to the byte I would assume that the max is in that area.
Till next time...
--Dave

I remember reading something on Luis Majano's site wrt to cfsavecontent use in high-use apps. If I remember correctly, he was saying that one of the problems he had with fusebox's cfsavecontent model for saving the view content was that he'd get instability and out-of-memory errors, and I believe he tracked it down to cfsavecontent. Interesting.
Anyway, good stuff.
Get rid of your <CFSAVECONTENT> and put a <CFFILE ACTION="APPEND"> in your loop.
--
Adam
--Dave
As Brian mentioned, I'm sure it's not a limitation of the tag but of the memory allocated to the JVM. This means your mileage will vary.
Something else to keep in mind is that the memory usage of building a string is no where near the physical size of the memory. If you monitor your heap, you'll see that the memory required to generate a 92MB file is significantly higher than 92MBs of RAM. So while the final size of the file written to disk may only be 92MBs, the actually amount of RAM that string consume in the JVM will be higher.
All you've demonstrated so far -as far as I can tell - is memory runs out if one uses more of it than is allcoated (the question perhaps is "allocated to what?")
What happens if you swap out the CFSAVECONTENT for simply concatenating the string together:
<cfset theRes = theRes & "#i#: Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Donec libero. Suspendisse bibendum. Cras id urna. Morbi tincidunt, orci ac convallis aliquam, lectus turpis varius lorem, eu posuere nunc justo tempus leo. Donec mattis, purus nec placerat bibendum, dui pede condimentum odio, ac blandit ante orci ut diam.">
My expectation would be you'd get the same error.
But if not, it does actually add some evidence to what you're suggesting. I don't see anything pointing specifically to CFSAVECONTENT here yet.
I'd also try varying your heap size in your JVM: you should see that "max out" figure change along with it.
--
Adam